springboot+jwt

somebodyoneday 2019-12-05

大概了解下SpringMVC和jwt,百度

 代码:

1.整体框架

springboot+jwt

2.controller

package com.yiyezhiqiu.jwt.jwt.controller;import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.JSONObject;import com.alibaba.fastjson.JSONPObject;import com.yiyezhiqiu.jwt.jwt.annotation.LoginAnnotation;import com.yiyezhiqiu.jwt.jwt.annotation.OtherPermit;import com.yiyezhiqiu.jwt.jwt.domain.Users;import com.yiyezhiqiu.jwt.jwt.service.IUsersService;import com.yiyezhiqiu.jwt.jwt.service.impl.GetToken;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.*;import javax.annotation.Resource;/** * 实现jwt,token验证 *  业务需求:没有登陆成功,不能访问其他页面,当登陆成功后,带入成功后返回给前端的token来访问其他页面 *  实现: * 1.了解springMVC,mvc在实现时有处理controller,那么我们在处理controller前对路径进行拦截,实现WebMvcConfigure接口。 * 2.拦截处理:实现HandlerInterceptor接口 ,在实现类中对请求的token进行验证。 * * * 具体做法: * 1.springboot整合mybatis,跑通能查数据库 * 2.写一个拦截处理器,即实现HandlerInterceptor接口 *      2.1:思路 *                对登陆操作不进行token验证,对非登陆操作要进行token验证 *      2.2:做法 *                  2.2.1:写两个注解,一个是用来对登陆进行控制,一个是其他页面进行控制 *                  2.2.2:开始写MyInterceptor中代码 * * * 3.实现WebMvcConfigure接口,对所有路径进行拦截,并把拦截器处理器实例加进来-》也就是实现拦截后使用拦截处理器去处理 * * * * * */@Slf4j@RestController@RequestMapping(value = "/users")public class UsersController {    @Autowired    IUsersService usersService;    @Resource(name = "GetToken")    GetToken getToken;    JSONObject jsonObject = new JSONObject();    /**     * 注册     */    @RequestMapping(value = "/register",method = RequestMethod.POST,produces = "application/json")    public JSONObject register(@RequestBody Users users){            int result = usersService.saveUsers(users);            if(result >0){                jsonObject.put("status",true);                jsonObject.put("message","新增成功");                return jsonObject;            }else{                jsonObject.put("status",false);                jsonObject.put("message","新增失败");                return jsonObject;            }    }    /**     * 登陆     * @param users     * @return     */    @LoginAnnotation    @RequestMapping(value = "/login",method = RequestMethod.POST,produces = "application/json")    public JSONObject usersLogin(@RequestBody Users users){    log.info("userName;"+users.getUserName()+",password:"+users.getPassword());    int result = usersService.findUsers(users);    if(result >0){        String token = getToken.token(users);        jsonObject.put("users",users);        jsonObject.put("message",token);    }else{         jsonObject.put("message","帐号或者密码错误");    }    return jsonObject;    }    /**     * 其他页面     * @return     */    @OtherPermit    @RequestMapping(value = "/otherPage",method = RequestMethod.GET)    public JSONObject otherPage(){        //模仿下登陆后,传入token,token验证后返回有效信息       JSONObject jsonObject = new JSONObject();       jsonObject.put("message","验证成功");       jsonObject.put("code",200);        return jsonObject;    }}

 3.service:

3.1 IUserService

package com.yiyezhiqiu.jwt.jwt.service;import com.yiyezhiqiu.jwt.jwt.domain.Users;public interface IUsersService {    public int saveUsers(Users users);    public int findUsers(Users users);} 3.2 impl下的UsersServiceImpl
package com.yiyezhiqiu.jwt.jwt.service.impl;import com.yiyezhiqiu.jwt.jwt.dao.UsersDao;import com.yiyezhiqiu.jwt.jwt.domain.Users;import com.yiyezhiqiu.jwt.jwt.service.IUsersService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;import org.springframework.stereotype.Service;import java.util.HashMap;import java.util.Map;@Servicepublic class UsersServiceImpl implements IUsersService {    @Autowired    UsersDao usersDao;    /**     * 新增     */    @Override    public int saveUsers(Users users) {        int result = usersDao.saveUsers(users);        return result ;    }    /**     * 查询     *     */    @Override    public int findUsers(Users users) {        Map<String,Object> params = new HashMap<>();        params.put("userName",users.getUserName());        params.put("password", users.getPassword());        Users user =  usersDao.findUsers(params);        if(null != user){            return 1;        }else{            return 0;        }    }}
3.3 impl下的GetToken
package com.yiyezhiqiu.jwt.jwt.service.impl;import com.auth0.jwt.JWT;import com.auth0.jwt.algorithms.Algorithm;import com.yiyezhiqiu.jwt.jwt.domain.Users;import org.springframework.context.annotation.Bean;import org.springframework.stereotype.Component;/** * 生成token */@Component("GetToken")public class GetToken {    public String token(Users users){        String token = "";        token  = JWT.create().withAudience(users.getUserName()).sign(Algorithm.HMAC256(users.getPassword()));        return token;    }}
4.dao层
package com.yiyezhiqiu.jwt.jwt.dao;import com.yiyezhiqiu.jwt.jwt.domain.Users;import org.apache.ibatis.annotations.Mapper;import org.springframework.stereotype.Component;import org.springframework.stereotype.Repository;import java.util.Map;@Mapper@Repositorypublic interface UsersDao {    /**     * 注册用户     */    public int saveUsers(Users users);    /**     * 查询用户     */    public Users findUsers (Map<String,Object> params);}
5.configure
package com.yiyezhiqiu.jwt.jwt.configure;import com.yiyezhiqiu.jwt.jwt.interceptor.MyInterceptor;import org.springframework.context.annotation.Configuration;import org.springframework.web.servlet.config.annotation.InterceptorRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configurationpublic class MyWebMvcConfigure  implements WebMvcConfigurer {    /**     * 拦截url并给相应拦截处理器处理     * @param registry     */    @Override    public void addInterceptors(InterceptorRegistry registry) {        registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**")//拦截所有                .excludePathPatterns("/users/register");//不拦截这个注册路径    }}6.interceptor
package com.yiyezhiqiu.jwt.jwt.interceptor;import com.alibaba.fastjson.JSONObject;import com.auth0.jwt.JWT;import com.auth0.jwt.JWTVerifier;import com.auth0.jwt.algorithms.Algorithm;import com.yiyezhiqiu.jwt.jwt.annotation.LoginAnnotation;import com.yiyezhiqiu.jwt.jwt.annotation.OtherPermit;import com.yiyezhiqiu.jwt.jwt.dao.UsersDao;import com.yiyezhiqiu.jwt.jwt.domain.Users;import com.yiyezhiqiu.jwt.jwt.service.IUsersService;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Configuration;import org.springframework.stereotype.Component;import org.springframework.stereotype.Service;import org.springframework.util.StringUtils;import org.springframework.web.method.HandlerMethod;import org.springframework.web.servlet.HandlerInterceptor;import org.springframework.web.servlet.ModelAndView;import javax.annotation.PostConstruct;import javax.annotation.Resource;import javax.servlet.ServletOutputStream;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.PrintWriter;import java.lang.reflect.Method;import java.util.HashMap;import java.util.Map;@Slf4j@Componentpublic class MyInterceptor implements HandlerInterceptor {    @Autowired    IUsersService usersService;    @Autowired    UsersDao usersDao;    private static MyInterceptor myInterceptor;    /**     * 这一段用来解决依赖注入不成功问题     */    @PostConstruct    public void init (){        myInterceptor = this;        myInterceptor.usersDao = this.usersDao;    }    /**     * springMVC正常流程时,处理器处理controller前被拦截处理     * @param request     * @param response     * @param handler     * @return     * @throws Exception     */    @Override    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {        JSONObject jsonObject = new JSONObject();        String token = request.getHeader("token");        //HandleMethod包含一些controller的方法,handler 就是一个全路径方法        HandlerMethod handlerMethod = (HandlerMethod)handler;        Method method = handlerMethod.getMethod();        //思路,通过判断请求的路径中的方法是否有相应的注解        if(method.isAnnotationPresent(LoginAnnotation.class)){            log.info("这是登陆");            return true;        }        //需要验证token        if(method.isAnnotationPresent(OtherPermit.class)){            //重置reset            response.reset();            //设置编码格式            response.setCharacterEncoding("utf-8");            response.setContentType("application/json");            //这里用reponse.getWriter()后面会报重复使用的错            ServletOutputStream pw = response.getOutputStream();            log.info("进来验证token");            if(StringUtils.isEmpty(token)){                jsonObject.put("message","no token");                pw.print(jsonObject.toJSONString());                return false;            }else{                try{                    String userName = JWT.decode(token).getAudience().get(0);                    log.info("userName;"+userName);                    Map<String,Object>  map = new HashMap<>();                    map.put("userName",userName);                    log.info("userDao:"+usersDao);                    log.info("userservice:"+usersService);                    Users users = myInterceptor.usersDao.findUsers(map);                    try{                        JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(users.getPassword())).build();                        jwtVerifier.verify(token);                        return true;                    }catch (Exception e){                        jsonObject.put("message","token invalid");                        jsonObject.put("code","401");                        pw.print(jsonObject.toJSONString());                        return false;                    }                }catch(Exception e){                    jsonObject.put("message","token invalid");                    jsonObject.put("code","401");                    pw.print(jsonObject.toJSONString());                    return false;                }            }        }        return false;    }    /**     * MVC时处理器处理controller后被拦截处理     * @param request     * @param response     * @param handler     * @param modelAndView     * @throws Exception     */    @Override    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {    }    /**     * 在返回视图前拦截     * @param request     * @param response     * @param handler     * @param ex     * @throws Exception     */    @Override    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {    }}
7.annotation;  7.1 LoginAnnotation  
package com.yiyezhiqiu.jwt.jwt.annotation;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;/** * 注明是登陆注解 */@Target({ElementType.METHOD,ElementType.TYPE}) //注解放在哪,方法上还是类还是哪里@Retention(RetentionPolicy.RUNTIME)//啥时候启用,运行时public @interface LoginAnnotation  {   boolean  get() default true;}7.2 Otherpermit  
package com.yiyezhiqiu.jwt.jwt.annotation;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;/** * 其他页面注解 */@Target({ElementType.METHOD,ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)public @interface OtherPermit {    boolean  other() default  true;}
8.domain
package com.yiyezhiqiu.jwt.jwt.domain;import lombok.Data;@Datapublic class Users {    private int id;    private String userName;    private String password;    private String gender;}
9.UsersMapping.xml
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" ><mapper namespace="com.yiyezhiqiu.jwt.jwt.dao.UsersDao">    <insert id = "saveUsers" parameterType="com.yiyezhiqiu.jwt.jwt.domain.Users" keyProperty="id" useGeneratedKeys="true">        insert into users(user_name,password,gender) values (#{userName},#{password},#{gender})    </insert>    <select id="findUsers" parameterType="java.util.HashMap" resultType="com.yiyezhiqiu.jwt.jwt.domain.Users">    select * from users where     user_name = #{userName}    <if test="password != null and password != ‘‘">        and password = #{password}    </if>    </select></mapper>10. application.yml
#端口号server:  port: 8088#数据库spring:  datasource:    driver-class-name: com.mysql.jdbc.Driver    url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&useSSL=false&allowMultiQueries=true    username: root    password: zhang#dao和xml映射mybatis:  mapper-locations: classpath:mapper/*.xml  type-aliases-package: com.yiyezhiqiu.jwt.jwt.domain#可以打印出sql语句logging:  level:    com:      yiyezhiqiu:        jwt:          jwt:           dao: debug11.pom.xml
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">    <modelVersion>4.0.0</modelVersion>    <parent>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-parent</artifactId>        <version>2.2.1.RELEASE</version>        <relativePath/> <!-- lookup parent from repository -->    </parent>    <groupId>com.yiyezhiqiu.jwt</groupId>    <artifactId>jwt</artifactId>    <version>0.0.1-SNAPSHOT</version>    <name>jwt</name>    <description>Demo project for Spring Boot</description>    <properties>        <java.version>1.8</java.version>    </properties>    <dependencies>        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-web</artifactId>        </dependency>        <dependency>            <groupId>org.mybatis.spring.boot</groupId>            <artifactId>mybatis-spring-boot-starter</artifactId>            <version>2.1.1</version>        </dependency>        <!--jwt 依赖-->        <dependency>            <groupId>io.jsonwebtoken</groupId>            <artifactId>jjwt</artifactId>            <version>0.9.1</version>        </dependency>        <dependency>            <groupId>com.alibaba</groupId>            <artifactId>fastjson</artifactId>            <version>1.2.54</version>        </dependency>        <dependency>            <groupId>com.auth0</groupId>            <artifactId>java-jwt</artifactId>            <version>3.4.0</version>        </dependency>        <dependency>            <groupId>org.slf4j</groupId>            <artifactId>slf4j-api</artifactId>        </dependency>        <dependency>            <groupId>mysql</groupId>            <artifactId>mysql-connector-java</artifactId>            <scope>runtime</scope>        </dependency>        <dependency>            <groupId>org.projectlombok</groupId>            <artifactId>lombok</artifactId>            <optional>true</optional>        </dependency>        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-test</artifactId>            <scope>test</scope>            <exclusions>                <exclusion>                    <groupId>org.junit.vintage</groupId>                    <artifactId>junit-vintage-engine</artifactId>                </exclusion>            </exclusions>        </dependency>    </dependencies>    <build>        <plugins>            <plugin>                <groupId>org.springframework.boot</groupId>                <artifactId>spring-boot-maven-plugin</artifactId>            </plugin>        </plugins>    </build></project>
总结:遇到问题与解决1.问题:在拦截器 MyInterceptor中以下注入失败,一直报空。
@AutowiredIUsersService usersService;@AutowiredUsersDao usersDao;解决:
/** * 这一段用来解决依赖注入不成功问题 */private static MyInterceptor myInterceptor;@PostConstructpublic void init (){    myInterceptor = this;    myInterceptor.usersDao = this.usersDao;}
解决后调用方式:
Users users = myInterceptor.usersDao.findUsers(map);解决该问题用到博客:https://blog.csdn.net/georgeshaw1/article/details/749430892.问题:在response.getWriter()时,报getWriter()has already been called for this response 异常
解决:  分析:该异常是response异常被其他调用了,我这里主要是因为在controller中有返回值给前端,然后在这里MyInterceptor中又用,就会导致这种情况   解决办法:    使用  ServletOutputStream pw = response.getOutputStream();代替3.
报有:ava.io.CharConversionException: Not an ISO 8859-1 character: [失]分析:这是因为使用getOutputStrieam不能输出中文字符,改成英文就好了4.多学习下注解的声明和使用场景

相关推荐

adonislu / 0评论 2020-01-17