当前位置:   article > 正文

登录校验,JWT令牌技术,过滤器(Filter)拦截器(interceptor)_jwtfilter

jwtfilter

登录功能:


    前端传递json格式的数据。username(用户名)password(密码)。controller层对数据进行接收,由于是接收json格式的数据,所以我们把它封装到一个对象里面,由于登录是员工进行登录,所以我们封装到员工表中,public Result login(@RequestBody Emp emp){}   接收json格式的数据,我们使用@RequestBody注解,封装到对象中。看到返回类型,我们自定义了一个返回的实体类:LoginInfo。

 

  1. @Data
  2. @NoArgsConstructor
  3. @AllArgsConstructor
  4. public class LoginInfo {
  5. private Integer id; //用户ID
  6. private String username; //用户名
  7. private String name; //姓名
  8. private String token; // 令牌
  9. }


    然后调用service层,进行业务处理。调用mapper层接口,把controller传递给service层的emp参数,传递给mapper层。

empService接口: 

  1. /**
  2. * 登录
  3. * @param emp
  4. * @return
  5. */
  6. LoginInfo login(Emp emp);
  7. }

empServiceImpl实现类: 

  a


    mapper层,根据参数对数据库进行查询,返回值类型是emp。如果查询到结果不为null,代表登录成功,查询结果为null,代表查询失败。

empMapper接口:

  1. /**
  2. * 根据用户名和密码查询
  3. * @param emp
  4. * @return
  5. */
  6. @Select("select * from emp where username = #{username} and password = #{password}")
  7. Emp getByUserNameAndPwd(Emp emp);
  8. }


    service层的实现类,根据mapper层的返回结果进行判断,如果返回的emp不是null,则对返回出来的数据进行封装 return new LoginInfo(emp.getId,emp.getUserName,emp.getname,null),如果查询到没有数据,就返回null。

 empServiceImpl实现类:

  1. @Override
  2. public LoginInfo login(Emp emp) {
  3. Emp e = empMapper.getByUserNameAndPwd(emp);
  4. if (e != null){ //登录成功 --生成令牌
  5. Map<String,Object> map = new HashMap<>(); //设置 payload的数据
  6. map.put("id",e.getId());
  7. map.put("username",e.getUsername());
  8. map.put("name",e.getName());
  9. String jwt = JwtUtils.generateJwt(map);
  10. return new LoginInfo(e.getId(),e.getUsername(),e.getName(),jwt);
  11. }
  12. return null;
  13. }


    由于我们的service层直接返回了 loginInfo,所以在返回给前端的时候还要进行判断,如果Logininfo不为null,返回Result.success(loginInfo)如果logininfo为null,return Result.error("用户名或密码错误");

LoginController:

  1. @Autowired
  2. private EmpService empService;
  3. @PostMapping("/login")
  4. public Result login(@RequestBody Emp emp){
  5. log.info("用户进行登录了...");
  6. LoginInfo loginInfo = empService.login(emp);
  7. if (loginInfo != null){
  8. return Result.success(loginInfo);
  9. }
  10. return Result.error("用户名或密码错误~~");
  11. }
引子:

  •     虽然我们写了 登录的接口,但是我们测试发现,就算在没有登录的情况下,用户还是可以随便对我们的系统进行访问。
  •     我们需要进行登录校验,如果用户登录,我们就下发jwt令牌,然后作为登录的标记,在每次用户请求的时候,都要携带这个jwt令牌,统一拦截器,会根据有没有令牌,进行校验。有就放行,没有就拦截。

登录校验:

  •   登录标记:用户登录之后,在后续的每一次请求中,都可以获取到该标记【会话技术】
  •     统一拦截:过滤器filter,拦截器interceptor

    会话技术:


        会话:用户打开浏览器,访问web服务器的资源,会话建立,直到有一方断开连接,会话结束。在一次会话中可以包含多次请求和响应。

简单的理解,一次会话,就像我们的一次打电话。 

断开了一个。

        会话跟踪:

一种维护浏览器状态的方法,服务器需要识别多次请求是否来自于同一浏览器,以便在同一次会话的多次请求间共享数据。


        会话跟踪方案:

            客户端会话跟踪技术:Cookie

cookie的三个自动:

①,在服务端设置cookie的时候,会自动在响应头中响应给客户端。 Set-Cookie:键 = 值

②客户端会自动保存,服务端返回的cookie   (右击浏览器 -> 点击检查 -> 点击应用 -> 点击左侧cookie)

③客户端在每次在向服务端,发送请求的时候,会自动携带cookie在请求头中。Cookie: 键=值

                优点:
  •  HTTP协议中支持的技术

                缺点:

  • 移动App无法使用Cookie
  • 不安全,用户可以自己禁用cookie
  • Cookie不能跨域

编写SessionController控制器层:

 

  1. //设置Cookie
  2. @GetMapping("/c1")
  3. public Result cookie1(HttpServletResponse response){
  4. response.addCookie(new Cookie("login_username","sde666")); //设置Cookie/响应Cookie
  5. return Result.success();
  6. }

可以发现,我在浏览器访问这个路径的时候,设置了一个cookie,cookie也是键值对格式的。

cookie的键是:login_username cookie的值是:sde666 

启动项目,在浏览器控制栏,输入:http://localhost:8080/s1 访问

服务端自动在响应头中把cookie返回给客户端。

 

可以看到客户端,自动保存了cookie

在SessionController类中,编写接口 c2 获取cookie

  1. //获取Cookie
  2. @GetMapping("/c2")
  3. public Result cookie2(HttpServletRequest request){
  4. Cookie[] cookies = request.getCookies();
  5. for (Cookie cookie : cookies) {
  6. if(cookie.getName().equals("login_username")){
  7. System.out.println("login_username: "+cookie.getValue()); //输出name为login_username的cookie
  8. }
  9. }
  10. return Result.success();
  11. }

执行 http://localhost:8080/c2 获取cookie

可以看到,客户端每次向服务端发送请求的时候,会在请求体中携带 cookie

看看浏览器控制台:

cookie的键和值都已经获取到了。

 

                区分跨域的三个维度:

  •   协议,IP/域名,端口

            服务端会话跟踪技术:Session
                优点:
  •  HTTP协议中支持的技术

                缺点:

  •   移动端APP无法使用Cookie
  •   不安全,用户可以自己禁用Cookie
  •    Cookie不能跨域

  

编写 SessionController控制器:

 

  1. /**
  2. * 存session
  3. * @param session
  4. * @return
  5. */
  6. @GetMapping("/s1")
  7. public Result session1(HttpSession session){
  8. log.info("HttpSession-s1: {}", session.hashCode());
  9. session.setAttribute("loginUser", "tom"); //往session中存储数据
  10. return Result.success();
  11. }

在浏览器输入http://localhost:8080/s1访问

可以看到服务器端的响应头中又Set-Cookie:JsessionId

编写:http://localhost:8080/s2 取session

  1. /**
  2. * 取session
  3. * @param request
  4. * @return
  5. */
  6. @GetMapping("/s2")
  7. public Result session2(HttpServletRequest request){
  8. HttpSession session = request.getSession();
  9. log.info("HttpSession-s2: {}", session.hashCode());
  10. Object loginUser = session.getAttribute("loginUser"); //从session中获取数据
  11. log.info("loginUser: {}", loginUser);
  12. return Result.success(loginUser);
  13. }

通过浏览器访问:

通过idea控制台观看:

 JWT令牌:


        优点:
  • 支持PC端、移动端
  •  解决集群环境下的认证问题
  •  减轻服务器端存储压力
        缺点:


            需要自己实现

        全称:

  • JSON Web Token (https://jwt.io/)
  • 定义了一种简洁的、自包含的格式,用于在通信双方以json数据格式安全的传输信息。
        
组成:

  •             第一部分:Header(头),记录令牌类型、签名算法等。 例如:{"alg":"HS256","type":"JWT"}
  •             第二部分:Payload(有效载荷),携带一些自定义信息、默认信息等。 例如:{"id":"1","username":"Tom"}
  •             第三部分:Signature(签名),防止Token被篡改、确保安全性。将header、payload融入,并加入指定秘钥,通过指定签名算法计算而来。
       

jwt依赖:

   

  1. <dependency>
  2.  <groupId>io.jsonwebtoken</groupId>
  3.   <artifactId>jjwt</artifactId>
  4.    <version>0.9.1</version>
  5. </dependency>
        生成令牌:

编写JwtTest类:


     

  1. /**
  2. * 生成令牌
  3. */
  4. @Test
  5. void testGenJwt(){
  6. Map<String,Object> claims = new HashMap<>();
  7. claims.put("id",18);
  8. claims.put("username","孙尚香");
  9. String jwt = Jwts.builder()
  10. .signWith(SignatureAlgorithm.HS256,"c2Rl") //设置令牌的签名算法和密钥
  11. .setExpiration(new Date(System.currentTimeMillis() + 2 * 3600 * 1000)) //设置过期时间
  12. .addClaims(claims) //往指定令牌存入数据
  13. .compact(); //生成令牌
  14. System.out.println(jwt);
  15. }

运行测试类:

 

        
解析令牌:

把上面刚刚,生成的令牌进行校验

  1. /**
  2. * 解析令牌
  3. */
  4. @Test
  5. void testParseJwt(){
  6. Claims claims = Jwts.parser()
  7. .setSigningKey("c2Rl") //
  8. .parseClaimsJws("eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE3MDI3MDc1NjksImlkIjoxOCwidXNlcm5hbWUiOiLlrZnlsJrpppkifQ.XW__woxh-1YVdR2rILavgr3tMPCqKjPjTioFC02MaZ4")
  9. .getBody(); //获取自定义内容
  10. System.out.println(claims);
  11. }

看idea控制台:

jwt令牌解析失败的4个情况:

①第一大类就是改写jwt令牌中三个部分中的任意一个

②第二大类就是,jwt令牌过期失效了。

演示一:(改写jwt令牌header部分)

测试效果:

演示二(更改令牌Payload部分)

效果测试:

演示三(更改signature部分)

效果演示:

演示四(jwt令牌过期)

运行这个单元测试方法,生成jwt令牌,放到下面的程序中解析。

进行解析测试:

完成登录成功下发Jwt令牌的操作:

在empServiceImpl,编写的login方法里面,调用了mapper接口里面的登录方法返回值是一个对象。如果登录成功,mapper返回的数据不为null,登录失败返回的数据是null

测试效果:

我输入用户名和密码,登录成功了,生成并下发jwt令牌。

 测试一下登录失败的情况。

我把密码输错,登录失败了,可以看到没有下发jwt令牌。

 过滤器Filter:


            概念:

  •  Filter 过滤器,是 JavaWeb 三大组件(Servlet、Filter、Listener)之一。
  •  过滤器可以把对资源的请求拦截下来,从而实现一些特殊的功能。
  • 过滤器一般完成一些通用的操作,比如:登录校验、统一编码处理、敏感字符处理等。
            快速操作:

  • 定义Filter:定义一个类。命名为DemoFilter。
  • 把这个类,实现Filter接口

我们可以看到, 当我们实现Filter接口时,程序会报错。

这个时候,我们点击 alt + enter 去实现这些方法。

上面有三个方法,要实现,也可以只实现一个方法,那就是doFilter方法。因为init方法和destory方法都是默认实现了已经。

  • init方法,初始化方法,程序运行的时候,就会执行。只能执行一次。
  • doFilter方法,执行拦截的方法,每次有请求经过的时候,都会执行,可以执行多次。
  • destory方法,程序销毁执行的方法,只会执行一次。


 

  1. @Slf4j
  2. public class DemoFilter implements Filter {
  3. @Override
  4. public void init(FilterConfig filterConfig) throws ServletException {
  5. log.info("DemoFilter init 方法执行了... ");
  6. }
  7. @Override
  8. public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
  9. log.info("DemoFilter diFilter 方法执行了 放行前执行...");
  10. chain.doFilter(servletRequest,servletResponse); //放行
  11. log.info("DemoFilter diFilter 方法执行了 放行后执行...");
  12. }
  13. @Override
  14. public void destroy() {
  15. log.info("DemoFilter destory 方法执行了...");
  16. }
  17. }

  配置Filter: 

  • Filter类上加@WebFilter注解,配置拦截路径。

引导类上加注解:

@ServletComponentScan 开启Servlet组件支持。

  1. @ServletComponentScan //开启spring boot对javaweb组件的支持(filter)
  2. @SpringBootApplication
  3. public class TilasRun {
  4. public static void main(String[] args) {
  5. SpringApplication.run(TilasRun.class, args);
  6. }
  7. }

运行测试:

 我先启动我的程序,可以发现,DemoFilter类中的init方法已经执行了。


 

在Apifox里面发送请求进行测试:

 客户端发起请求,先进入到Filter拦截器,执行了放行前的方法,放行之后,进入到controller,执行完毕之后,又回到了Filter类中,执行了放行之后的方法,然后在返回给客户端。

关系应用程序:

 


        Filter详解:


 放行后访问对应资源,资源访问完成后,还会回到Filter中吗?
           答案:会 回到filter类中

 执行流程:


如果回到Filter中,是重新执行还是执行放行后的逻辑呢?

答案:会执行放行后的逻辑

过滤器的放行:

调用 FilterChain 接口中的 doFilter方法。把请求(ServletRequest)和 响应(ServletResponse)作为参数传递进去。

 

  1. @Override
  2. public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
  3. log.info("DemoFilter diFilter 方法执行了 放行前执行...");
  4. chain.doFilter(servletRequest,servletResponse); //放行
  5. log.info("DemoFilter diFilter 方法执行了 放行后执行...");
  6. }

如果我们没有调用 FilterChain接口中的 doFilter方法,那么就代表没有放行。

 

  1. @Override
  2. public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
  3. log.info("DemoFilter diFilter 方法执行了 放行前执行...");
  4. // chain.doFilter(servletRequest,servletResponse); // 我把这一行注释了,表示不放行,那么请求就被拦截在这了。
  5. log.info("DemoFilter diFilter 方法执行了 放行后执行...");
  6. }

重启服务器测试:

  • 执行了,查询所有部门的接口,发现没有执行 DeptController中的方法,证明请求没有执行。
  • 执行了,登录接口,发现没有执行 LoginController中的方法,证明请求没有执行。

 调用查询全部的部门接口

调用登录接口:

 

看看 idea的控制台信息:


            拦截路径解析:

        


                拦截具体路径:


                    /login    只有访问 /login 路径时,才会被拦截。

  1. @WebFilter("/login") //拦截 login请求
  2. public class DemoFilter implements Filter {
  3. }

测试:

 查询全部的部门信息:

在Apifox测试,可以发现,Filter拦截器,没有拦截这个/depts请求。

登录接口: 

在Apifox测试,拦截器拦截了/login这个请求。


                目录拦截:

  /depts/*   只有访问/deps下的所有资源,才会被拦截。

  1. @Slf4j
  2. //@WebFilter(urlPatterns = "/*")
  3. //@WebFilter("/login") //拦截 login请求
  4. @WebFilter(urlPatterns = "/depts/*") //拦截depts目录下的所有请求
  5. public class DemoFilter implements Filter {
  6. @Override
  7. public void init(FilterConfig filterConfig) throws ServletException {
  8. log.info("DemoFilter init 方法执行了... ");
  9. }
  10. }

测试:

登录接口:

在Apifox测试,可以发现没有拦截我的登录接口 

查看所有部门接口:

在Apifox测试,可以发现拦截了我的查询部门相关的接口。

 


                拦截所有:


/*     访问所有资源,都会被拦截


            过滤器链:


                介绍:


 一个web应用中,可以配置多个过滤器,这多个过滤器就形成了一个过滤器链。


                顺序:


 注解配置的Filter,优先级是按照过滤器类名(字符串)的自然排序。

创建AbcFilter类:

  1. @Slf4j
  2. @WebFilter("/*")
  3. public class AbcFilter implements Filter {
  4. @Override
  5. public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
  6. log.info("AbcFilter doFilter 方法执行了 放行前");
  7. chain.doFilter(servletRequest,servletResponse); // 放行
  8. log.info("AbcFilter doFilter 方法执行了 放行后");
  9. }
  10. }

还有一个filter类就是上面用的DemoFilter类

  1. @Slf4j
  2. @WebFilter(urlPatterns = "/*")
  3. //@WebFilter("/login") //拦截 login请求
  4. //@WebFilter(urlPatterns = "/depts/*") //拦截depts目录下的所有请求
  5. public class DemoFilter implements Filter {
  6. @Override
  7. public void init(FilterConfig filterConfig) throws ServletException {
  8. log.info("DemoFilter init 方法执行了... ");
  9. }
  10. @Override
  11. public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
  12. log.info("DemoFilter diFilter 方法执行了 放行前执行...");
  13. chain.doFilter(servletRequest,servletResponse); //放行
  14. log.info("DemoFilter diFilter 方法执行了 放行后执行...");
  15. }
  16. @Override
  17. public void destroy() {
  18. log.info("DemoFilter destory 方法执行了...");
  19. }
  20. }

这两个过滤器,就成了过滤器链了,我们启动程序观察执行流程。

在Apifox里面测试:执行查询全部的部门信息接口。

①先执行了 AbcFilter中的放行前的方法。

开始:

在Apifox里面发送请求测试:

 第一步:

第二步:

第三步:

第四步:

第五步:

最后:

看看idea的控制台:

        登录校验-Filter:


            所有的请求,拦截到了之后,都需要校验令牌吗?
                有一个例外,登录请求不用拦截。
            拦截到请求后,什么情况下才可以放行,执行操作业务?
                有令牌,且令牌校验通过(合法);否则都返回未登录错误结果

            登录拦截步骤:

  • 1,获取请求url。
  • 2,判断请求url中是否包含login,如果包含,说明是登录操作,放行。
  • 3,获取请求头中的令牌(token)。
  • 4,判断令牌是否存在,如果不存在,响应401。
  • 5,解析token,如果解析失败,响应401 。
  • 6,放行。

  1,获取请求的url,2,判断请求头中是否包含login

  1. @Override
  2. public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
  3. HttpServletRequest request = (HttpServletRequest) servletRequest;
  4. HttpServletResponse response = (HttpServletResponse) servletResponse;
  5. //获取请求url。
  6. String url = request.getRequestURL().toString();
  7. //判断请求url中是否包含login,如果包含,说明是登录操作,放行。
  8. if (url.contains("/login")){
  9. log.info("是登录请求,直接放行{}",url);
  10. chain.doFilter(request,response);
  11. return;
  12. }
  13. }

3,获取请求头中的令牌:

  1. //获取请求头中的令牌(token)。
  2. String jwt = request.getHeader("token");

4,判断令牌是否存在:

  1. //判断令牌是否存在,如果不存在,响应401。
  2. if (!StringUtils.hasLength(jwt)){
  3. log.info("没有携带jwt令牌",jwt);
  4. //如果没有 jwt令牌,设置响应码为 401
  5. response.setStatus(401);
  6. return;
  7. }

5,解析令牌:

  1. //解析token,如果解析失败,响应401 。
  2. try {
  3. JwtUtils.parseJWT(jwt);
  4. } catch (Exception e) {
  5. log.info("令牌解析出错{}",e);
  6. response.setStatus(401);
  7. return;
  8. }

6,放行:

  1. //放行。
  2. chain.doFilter(request,response);
 登录测试:

我在Apifox里面进行登录测试,看看拦截器是否直接放行了,登录接口。

查看拦截器:

直接放行,访问web资源(LoginController)

测试,jwt令牌为null的情况。

我在Apifox里面进行测试,访问查询全部的部门信息接口,未携带jwt令牌。

拦截到了请求:

令牌为null

看Apifox返回的信息:

测试不合法的jwt令牌:

我的jwt令牌的最后以为,多加了一个0 是错误的令牌。我在请求头中携带这个令牌,向后端发送请求。

拦截,因为不是登录请求。

有jwt令牌:

非法的jwt令牌,解析出现异常。

在Apifox查看效果:

成功测试-jwt令牌合法

我在向后端发起请求的时候,携带合法的jwt令牌

不是登录请求,拦截。

有令牌:

合法的令牌:

成功访问到web资源

Apifox的返回数据:

拦截器Interceptor:


       
            概念:


 是一种动态拦截方法调用的机制,类似于过滤器。Spring框架中提供的,主要用来动态拦截控制器方法的执行。


            作用:


 拦截请求,在指定的方法调用前后,根据业务需要执行预先设定的代码。

  •  1,定义拦截器,实现HandlerInterceptor接口,并重写其所有方法。
  •  2,注册拦截器
1,定义一个类,DemoInterceptor实现 HandlerInterceptor接口。

  1. @Slf4j
  2. @Component
  3. public class DemoInterceptor implements HandlerInterceptor {
  4. // controller 方法运行之前执行 返回值是 boolean类型 true表示放行 false表示不放行
  5. @Override
  6. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
  7. log.info("DemoInterceptor preHandle 方法执行了");
  8. return true;
  9. }
  10. // controller 方法运行之后执行
  11. @Override
  12. public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
  13. log.info("DemoInterceptor postHandle 方法执行了");
  14. }
  15. // 最后运行的
  16. @Override
  17. public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
  18. log.info("DemoInterceptor afterCompletion 方法执行了");
  19. }
  20. }
2,注册拦截器:

      
        @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(demoInterceptor).addPathPatterns("/**");  //表示拦截所有请求的路径
    } 

表示我要拦截所有的请求。

  1. /**
  2. * 配置类---配置拦截器
  3. */
  4. @Slf4j
  5. @Configuration
  6. public class WebConfig implements WebMvcConfigurer {
  7. @Autowired
  8. private DemoInterceptor demoInterceptor;
  9. @Override
  10. public void addInterceptors(InterceptorRegistry registry) {
  11. registry.addInterceptor(demoInterceptor).addPathPatterns("/**"); //表示拦截所有请求的路径
  12. }
  13. }

在Apifox测试,是否能够拦截到我的所有请求。

方法执行前拦截到了。

web资源,运行后执行。

访问到了deptController:

最后执行的方法也执行了。

查看Apifox的返回数据。

拿到了所有的部门数据。

查看一下,执行流程。

拦截器:HandlerInterceptor接口解析:
         // 返回值类型是 boolean  true代表放行mfalse代表不放行。
default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
       throws Exception {

    return true;
}

 

  1. default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
  2. throws Exception {
  3. return true;
  4. }

后两个方法:

这两个方法在过滤器中,一般不常使用,主要是第一个方法。

 

  1. // handlerInterceptor接口的第二个方法。
  2. default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
  3. @Nullable ModelAndView modelAndView) throws Exception {
  4. }
  5. // handlerInterceptor接口的第三个方法。
  6. default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
  7. @Nullable Exception ex) throws Exception {
  8. }

 

过滤器路径详解:
        一级路径:


/*        能匹配/depts,/emps,/login,不能匹配 /depts/1

任意路径:

            /**     能匹配/depts,/depts/1,/depts/1/2

  1. @Override
  2. public void addInterceptors(InterceptorRegistry registry) {
  3. registry.addInterceptor(demoInterceptor).addPathPatterns("/**"); //表示拦截所有请求的路径
  4. }

测试效果:

登录接口拦截:

idea效果:

查询所有部门信息接口:

idea效果: 

目录匹配一级:

 /depts/*    /depts下的下一级路径    能匹配/depts/1,不能匹配/depts/1/2,/depts

  1. @Override
  2. public void addInterceptors(InterceptorRegistry registry) {
  3. // 拦截除了登录以外的所有路径
  4. registry.addInterceptor(demoInterceptor).addPathPatterns("/depts/*");
  5. }

测试查询单个emp的接口:

 

idea效果: 

测试根据id查询部门信息接口: 

idea效果:

目录匹配任意级:

             /depts/**       /detps下的任意级路径      能匹配/depts,depts/1/2  不能匹配 emps/1
         

  1. @Override
  2. public void addInterceptors(InterceptorRegistry registry) {
  3. // 拦截除了登录以外的所有路径
  4. registry.addInterceptor(demoInterceptor).addPathPatterns("/depts/**");
  5. }
过滤器,拦截路径的排除(excludePathPatterns):

 excludePathPatterns:可以排除,过滤器不拦截的路经。

  1. @Override
  2. public void addInterceptors(InterceptorRegistry registry) {
  3. registry.addInterceptor(demoInterceptor).addPathPatterns("/**").excludePathPatterns("/login"); //我在preHandle方法中已经判断了 .excludePathPatterns("/login");
  4. }

测试: 

在Apifox发送登录测试:

 

ieal效果:

测试查询全部的部门信息:

 

然后在到LoginContriller接口:


            Filter和interceptot的区别:

  • 接口规范不同:过滤器需要实现Filter接口,而拦截器需要实现HandlerInterceptor接口。
  • 拦截范围不同:过滤器Filter会拦截所有的资源,而Interceptor只会拦截Spring环境中的资源。
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/729490
推荐阅读
相关标签
  

闽ICP备14008679号