赞
踩
本人最近钻研SpringMVC,都是学习感悟与个人看法,接受任何提问与建议,希望大家提出自己独特的见解,谢谢。
也可以进入我的b站主页,观看在线教程,视频中写出了当前文章中未出现的技术,而且在拦截器上也做出了许多改动,使用了两个拦截器来进行认证与权限;
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <configuration>
- <source>8</source>
- <target>8</target>
- </configuration>
- </plugin>
- </plugins>
- </build>
- <packaging>war</packaging>
- <dependencies>
-
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-web</artifactId>
- <version>5.3.5</version>
- </dependency>
-
- <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-webmvc</artifactId>
- <version>5.3.5</version>
- </dependency>
-
- <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context</artifactId>
- <version>5.3.5</version>
- </dependency>
-
- <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-core</artifactId>
- <version>5.3.5</version>
- </dependency>
- <!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-beans</artifactId>
- <version>5.3.5</version>
- </dependency>
-
-
- <dependency>
- <groupId>org.glassfish.web</groupId>
- <artifactId>jstl-impl</artifactId>
- <version>1.2</version>
- <!-- 去除依赖 -->
- <exclusions>
- <exclusion>
- <groupId>javax.servlet</groupId>
- <artifactId>servlet-api</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
-
- <dependency>
- <groupId>javax.servlet</groupId>
- <artifactId>javax.servlet-api</artifactId>
- <version>3.1.0</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>com.alibaba</groupId>
- <artifactId>fastjson</artifactId>
- <version>1.2.76</version>
- </dependency>
- <dependency>
- <groupId>c3p0</groupId>
- <artifactId>c3p0</artifactId>
- <version>0.9.1.2</version>
- </dependency>
- <dependency>
- <groupId>mysql</groupId>
- <artifactId>mysql-connector-java</artifactId>
- <version>8.0.20</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-jdbc</artifactId>
- <version>5.3.5</version>
- </dependency>
- <!-- https://mvnrepository.com/artifact/org.springframework/spring-websocket -->
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-websocket</artifactId>
- <version>5.3.5</version>
- </dependency>
-
-
- <dependency>
- <groupId>org.mybatis</groupId>
- <artifactId>mybatis-spring</artifactId>
- <version>1.3.0</version>
- </dependency>
-
- <dependency>
- <groupId>org.mybatis</groupId>
- <artifactId>mybatis</artifactId>
- <version>3.4.1</version>
- </dependency>
-
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- <version>1.7.25</version>
- </dependency>
-
- <dependency>
- <groupId>io.jsonwebtoken</groupId>
- <artifactId>jjwt</artifactId>
- <version>0.9.0</version>
- </dependency>
- <!--redis -->
-
- <!--spring-data-redis版本不能太高害怕有冲突 -->
-
- <dependency>
-
- <groupId>org.springframework.data</groupId>
-
- <artifactId>spring-data-redis</artifactId>
-
- <version>1.7.5.RELEASE</version>
-
- </dependency>
-
- <dependency>
-
- <groupId>redis.clients</groupId>
-
- <artifactId>jedis</artifactId>
-
- <version>2.9.0</version>
-
- </dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-databind</artifactId>
- <version>2.11.4</version>
- </dependency>
- <!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
- <dependency>
- <groupId>commons-codec</groupId>
- <artifactId>commons-codec</artifactId>
- <version>1.10</version>
- </dependency>
-
- </dependencies>
- @Configuration
- @EnableWebMvc
- @ComponentScan(basePackages = "com.cjj.controller")
- public class ServletConfig implements WebMvcConfigurer {
-
- @Bean
- public ViewResolver viewResolver(){
- InternalResourceViewResolver viewResolver=new InternalResourceViewResolver();
- viewResolver.setPrefix("/WEB-INF/views/");
- viewResolver.setSuffix(".html");
- viewResolver.setExposeContextBeansAsAttributes(true);
- return viewResolver;
- //InternalResourceViewResolver 是 Spring MVC 中最常用的视图解析器
- // 它用于解析 JS P或 HTML 等资源文件。该解析器会将逻辑视图名称加上前缀和后缀
- // 例如将逻辑视图名称 “hello” 解析为 “/WEB-INF/views/hello.html”。
- }
- public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
- configurer.enable();
- }
- @Bean
- public MyInterceptor getMyInterceptor(){
- return new MyInterceptor();
- }
- public void addInterceptors(InterceptorRegistry registry) {
- registry.addInterceptor(getMyInterceptor())
- .addPathPatterns("/**")
- .excludePathPatterns("/login2")
- .excludePathPatterns("/")
- .excludePathPatterns("/testredis")
- .excludePathPatterns("/image/**")
- .excludePathPatterns("/js/**")
- .excludePathPatterns("/css/**");
- }
- }
- @Configuration
- // Reposity @service @Bean
- @MapperScan(basePackages="com.cjj.Dao")
-
- @ComponentScan(basePackages = "com.cjj" ,excludeFilters =
- {@ComponentScan.Filter(type = FilterType.ANNOTATION,value ={EnableWebMvc.class, Controller.class})})
- //是除了web层的所有的Bean
- @PropertySource({"classpath:jdbc.properties"})
- public class RootConfig {
-
- @Value("${driverClass}")
- private String driver;
- @Value("${url}")
- private String url;
-
- @Value("${root}")
- private String root;
-
- @Value("${password}")
- private String password;
-
- @Bean(name="datasource")
- public DataSource getDataSource(){
-
- ComboPooledDataSource dataSource=new ComboPooledDataSource();
- try {
- dataSource.setDriverClass(driver);
- dataSource.setJdbcUrl(url);
- dataSource.setUser(root);
- dataSource.setPassword(password);
- } catch (PropertyVetoException e) {
- e.printStackTrace();
- }
- return dataSource;
- }
-
-
- @Bean(name = "jdbctemplate")
- public JdbcTemplate getJdbcTemplate(DataSource dataSource){
- JdbcTemplate jdbcTemplate=new JdbcTemplate(dataSource);
- return jdbcTemplate;
- }
-
- //mybatis的配置
- @Bean
- public SqlSessionFactoryBean sqlSessionFactoryBean() throws IOException {
- System.out.println("SqlSessionFactoryBean---------------------------");
- ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
- SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();//mybatis-plus插件类
- sqlSessionFactoryBean.setDataSource(getDataSource());//数据源
- sqlSessionFactoryBean.setMapperLocations(resourcePatternResolver.getResources("classpath:mappers/*.xml"));
- return sqlSessionFactoryBean;
- }
- }
让我们可以不需要配置xml文件,就能访问到mappers下的所有映射文件,jdbc.properties我就不献上了,大家根据自己的数据库配置来;
- public class MvcApplication extends AbstractAnnotationConfigDispatcherServletInitializer {
- @Override
- protected Class<?>[] getRootConfigClasses() {
- //返回的带有@Configuration注解的类用来配置ContextLoaderListener;
- System.out.println("RootConfig-----------");
- return new Class[]{RootConfig.class};
- }
-
- @Override
- protected Class<?>[] getServletConfigClasses() {
- //将一个或多个路径映射到DispatcherServlet上;
- System.out.println("ServletConfig-----------");
- return new Class[]{ServletConfig.class};
- }
-
- @Override
- protected String[] getServletMappings() {
- // /*拦截所有http请求,包括.jsp,都作为控制器类的请求路径处理;
- System.out.println("getServletMappings-----------");
- return new String[]{"/"};
- }
-
- }
配置全都部署好了,接下来开始我们的实体类
- @Component
- public class User {
- private int id;
- private String username;
- private String password;
- private String token;
- private int rid;
- private List<privilege> pprivilegerList;
-
- public User() {
- }
-
- public User(String username, String password, String token) {
- this.username = username;
- this.password = password;
- this.token = token;
- }
-
- public User(int id, String username, String password, String token, int rid) {
- this.id = id;
- this.username = username;
- this.password = password;
- this.token = token;
- this.rid = rid;
- }
- public int getId() {
- return id;
- }
-
- public void setId(int id) {
- this.id = id;
- }
-
- public String getUsername() {
- return username;
- }
-
- public void setUsername(String username) {
- this.username = username;
- }
-
- public String getPassword() {
- return password;
- }
-
- public void setPassword(String password) {
- this.password = password;
- }
-
- public String getToken() {
- return token;
- }
-
- public void setToken(String token) {
- this.token = token;
- }
-
-
-
- public int getRid() {
- return rid;
- }
-
- public void setRid(int rid) {
- this.rid = rid;
- }
-
- public List<privilege> getPprivilegerList() {
- return pprivilegerList;
- }
-
- public void setPprivilegerList(List<privilege> pprivilegerList) {
- this.pprivilegerList = pprivilegerList;
- }
-
- @Override
- public String toString() {
- return "User{" +
- "id=" + id +
- ", username='" + username + '\'' +
- ", password='" + password + '\'' +
- ", token='" + token + '\'' +
- ", rid=" + rid +
- '}';
- }
- }
- @Component
- public class privilege {
- private int id;
- private String demoname;
- private int pid;
-
- public privilege() {
- }
-
- public privilege(int id, String demoname, int pid) {
- this.id = id;
- this.demoname = demoname;
- this.pid = pid;
- }
-
- public int getId() {
- return id;
- }
-
- public void setId(int id) {
- this.id = id;
- }
-
- public String getDemoname() {
- return demoname;
- }
-
- public void setDemoname(String demoname) {
- this.demoname = demoname;
- }
-
- public int getPid() {
- return pid;
- }
-
- public void setPid(int pid) {
- this.pid = pid;
- }
- }
- @Repository
- @Mapper
- public interface UserDao {
- public User login(User user);
-
- public List<privilege> getprivilege(User user);
- }
- <mapper namespace="com.cjj.Dao.UserDao">
- <select id="login" parameterType="com.cjj.Model.User" resultType="com.cjj.Model.User">
- select id,username,password,token,rid FROM `user` where `user`.username=#{username} and `user`.`password`=#{password}
- </select>
- <resultMap id="wei" type="com.cjj.Model.privilege" >
- <id column="id" property="id"/>
- <result column="demoname" property="demoname"/>
- <result column="rid" property="rid"/>
- </resultMap>
- <select id="getprivilege" parameterType="com.cjj.Model.User" resultMap="wei">
- SELECT a.id ,b.demoname ,b.pid FROM user
- INNER JOIN role ON role.id = user.rid
- INNER JOIN privilege a ON a.id = role.id
- INNER JOIN privilege b on a.id = b.pid
- WHERE user.rid= #{rid}
- </select>
- </mapper>
- public interface UserServiceIdao {
- public User login(User user);
-
- public List<privilege> getprivilege(User user);
- }
实现接口
- @Service
- public class UserService implements UserServiceIdao {
- @Autowired
- private UserDao userDao;
-
- @Override
- public User login(User user) {
- return userDao.login(user);
- }
-
- @Override
- public List<privilege> getprivilege(User user) {
- return userDao.getprivilege(user);
- }
- }
在咱们进入控制层之前,咱们先来配置好jwt类的生成与解析
- public class JWTuuid {
- private static final long time =60*60*24*1000;
- private static final String signature="weifeng00000x";//秘钥
-
- public static final String createjwt(String name, User user)
- {
- JwtBuilder jwtBuilder= Jwts.builder();
- String jwttoken=jwtBuilder
- //header -- 设置头
- .setHeaderParam("typ","JWT")
- .setHeaderParam("alg","HS256")//加密算法
-
- //payload----载荷
- .claim("username",name)
- .claim("stu", user)
- //主题
- .setSubject("weifeng-test")
- //有效时间
- .setExpiration(new Date(System.currentTimeMillis()+time))//从当前开始,24小时
- //jwt id
- .setId(UUID.randomUUID().toString())
- //签名 signature
- .signWith(SignatureAlgorithm.HS256,signature)
- .compact();
- return jwttoken;
- }
- // 解析 JWT
- public static Claims testJWT(String jwt) {
- try{
- Claims claims = Jwts.parser()
- .setSigningKey(signature) //放入秘钥
- .parseClaimsJws(jwt) //放入需要解析的串
- .getBody();
- return claims;
- }catch (Exception e){
- e.printStackTrace();
- // 如果对于秘钥解析错误那么放回null
- return null;
- }
- }
-
- public static boolean validateToken(String token) {
- try {
- Jwts.parser().setSigningKey(signature).parseClaimsJws(token);
- return true;
- } catch (Exception e) {
- return false;
- }
- }
-
- }
终于来到了咱们的控制层
- @RestController
- public class UserController {
-
- @Autowired
- UserService userService;
-
- @CrossOrigin(origins = "http://localhost:63342")
- @PostMapping("/login2")
- @ResponseBody
- public Object login2(@RequestBody JSONObject json, HttpServletRequest req, HttpServletResponse response)
- {
- String username=json.getString("username");
- String password=json.getString("password");
- User user =new User(username,password,"");
- System.out.println("username "+username+"-----pwd "+password);
- User login = userService.login(user);
- System.out.println("login的值为---------"+login);
- if(login!=null)
- {
- req.getSession().setAttribute("user",login);
- String createjwt = JWTuuid.createjwt(username, user);
- user.setToken(createjwt);
- System.out.println("jwt码--"+createjwt);
-
- // 将token写入响应头中
- response.addHeader("Authorization", "Bearer " + createjwt);
- response.setContentType("application/json;charset=utf-8");
- return createjwt;
- }
- else {
- String error="用户名或密码错误";
- // 设置HTTP状态码为401 Unauthorized
- response.setStatus(HttpStatus.UNAUTHORIZED.value(),"用户名或密码错误");
- //response.setStatus(HttpStatus.UNAUTHORIZED.value());
- response.setContentType("application/json;charset=utf-8");
- // 返回
- return error;
- }
- }
-
- @RequestMapping(value = "/aa",method = RequestMethod.GET)
- public ModelAndView getaa(HttpServletRequest req)
- {
- System.out.println("进来这个方法 getaa()");
- ModelAndView mv=new ModelAndView();
- mv.setViewName("aa");
-
- return mv;
- }
-
- @GetMapping("/demo")
- @ResponseBody
- public Object getstu(@RequestParam("demo") int demo,HttpServletRequest req){
- System.out.println("进来这个方法 getstu()");
- System.out.println("demo : "+demo);
- // System.out.println("token: "+token);
- // Claims claims=JWTuuid.testJWT(token);
- // if(claims==null){
- // System.out.println("jwt码有误,勿扰");
- // return "jwt码有误,勿扰";
- // }
- List<privilege> user = userService.getprivilege((User) req.getSession().getAttribute("user"));
- for (privilege s : user) {
- System.out.println(s.getDemoname());
- }
- // String obj=claims.getSubject();
- // System.out.println("提交主题:"+obj);
- return user;
- }
-
-
- }
其实我的登录是有些问题的,我返回的直接是个字符串,照理说应该是一个result集合,然后给状态或是其他什么的,将就看看吧,哈哈;
- public class MyInterceptor implements HandlerInterceptor {
- @Override
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
- System.out.println("===============请求处理前(1)===================");
- String path=request.getRequestURL().toString();
- if(path.indexOf("/login2")>=0){
- System.out.println("确实是login方法------");
- return true;
- }
- System.out.println("--------------------------------------"+path);
- Object obj=request.getSession().getAttribute("user");
- System.out.println(obj+"---------------------MyInterceptor");
- if(obj!=null)
- return true;
-
- // 获取Authorization请求头中的token
- String authHeader = request.getHeader("Authorization");
- if (authHeader != null && authHeader.startsWith("Bearer ")) {
- String token = authHeader.substring(7);
- System.out.println("截取的token");
- // 验证token
- if (JWTuuid.validateToken(token)) {
- return true; // 验证通过,继续执行后续操作
- }
- }
-
- //request.setAttribute("msg","还没有登陆,请先登录");
- request.getRequestDispatcher("index.html").forward(request,response);
- return false;
- }
-
- @Override
- public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
- // HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
- System.out.println("===============请求处理后,生成视图之前(2)===================");
- //assert modelAndView != null;
- // System.out.println("modelviewname============="+modelAndView.getViewName());
- }
-
-
- @Override
- public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
- // HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
- System.out.println("===============结束时调用(3)===================");
- }
- }
我觉得我的拦截器,写的有问题,虽然能成功使用,但还是希望大家提出各自独特的见解;
index.html
-
- <html>
- <head>
- <meta charset="UTF-8">
- <title>$Title$</title>
- <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
- </head>
- <body>
- 用户:<input id="username" type="text" name="username" placeholder="请输入用户">
- 密码:<input id="password" type="password" name="password" placeholder="请输入密码">
- <button id="login" value="登录"/>
- 登录
- <button type="reset" value="重置"/>
- 重置
-
-
- <script>
- $("#login").click(function (){
- let username = document.getElementById("username").value;
- let password = document.getElementById("password").value;
- let user={};
- user.username=username;
- user.password=password;
- console.log(user);
- $.ajax({
- url: 'http://localhost:9090/login2', // 请求的API接口地址
- //http://iwenwiki.com:8088/api/FingerUnion/list.php
- type: 'POST',
- // headers:{
- // token:"wawa"
- // },
- dataType: 'text',
- contentType:"application/json",
- data:JSON.stringify(user) ,
- success: function (e) {
- alert("key为:"+e);
- console.log("key为:"+e);
- localStorage.setItem('token', e);
- sessionStorage.setItem('token',e);
- window.location.href="http://localhost:9090/aa";
- // TODO: 处理接收到的数据
- },
- error: function (e) {
- alert("账号或密码错误!!");
- }
- });
- });
-
- // let p=new Promise((resolve, reject) =>{
- </script>
- </body>
- </html>
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Title</title>
- <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
- </head>
- <body>
- <p id="pp">你好你好你好你好喝牛奶</p>
- 操作功能:<button type="button" id="caoz" value="请操作"/>
-
-
- </body>
- </html>
- <script>
- $("#caoz").click(function (){
- $.ajax({
- url: 'http://localhost:9090/demo', // 请求的API接口地址
- type:"get",
- dataType: 'json',
- contentType:"application/json",
- data:{
- demo:20040309,
- },
- headers:{
- "Authorization":localStorage.getItem('token'),
- },
- success:function (e){
- alert("success回调执行了")
- for(var i = 0; i < e.length; i++) {
- var name = e[i].demoname;
- console.log("权限有", name);
- }
- },
- error:function (e){
- alert("error回调执行了")
- },
- });
- })
- </script>
到此,我个人学习的收获就完了,希望能看到这里的朋友,学习永无瓶颈,天天开心,一直保持着一颗追求新技术的心。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。