zoukankan      html  css  js  c++  java
  • SpringBoot之HandlerInterceptor拦截器的使用 ——(一)

    HandlerInterceptor简介
    拦截器我想大家都并不陌生,最常用的登录拦截、或是权限校验、或是防重复提交、或是根据业务像12306去校验购票时间,总之可以去做很多的事情。
    我仔细想了想
    这里我分三篇博客来介绍HandlerInterceptor的使用,从基本的使用、到自定义注解、最后到读取body中的流解决无法多次读取的问题。

    1、定义实现类
    定义一个Interceptor 非常简单方式也有几种,我这里简单列举两种
    1、类要实现Spring 的HandlerInterceptor 接口
    2、类继承实现了HandlerInterceptor 接口的类,例如 已经提供的实现了HandlerInterceptor 接口的抽象类HandlerInterceptorAdapter

    2、HandlerInterceptor方法介绍

    boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
                throws Exception;
    
        void postHandle(
                HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
                throws Exception;
    
        void afterCompletion(
                HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
                throws Exception;

    preHandle:在业务处理器处理请求之前被调用。预处理,可以进行编码、安全控制、权限校验等处理;
    postHandle:在业务处理器处理请求执行完成后,生成视图之前执行。后处理(调用了Service并返回ModelAndView,但未进行页面渲染),有机会修改ModelAndView (这个博主就基本不怎么用了);
    afterCompletion:在DispatcherServlet完全处理完请求后被调用,可用于清理资源等。返回处理(已经渲染了页面);
    接下来让我们来实现一个登陆 and 访问权限校验的拦截器吧

    拦截器实现

    • 新建TestFilter
    • package com.xxx.core.filter;
      
      import com.xxx.common.exception.FastRuntimeException;
      import org.slf4j.Logger;
      import org.slf4j.LoggerFactory;
      import org.springframework.web.servlet.ModelAndView;
      import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
      
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      
      
      public class TestFilter extends HandlerInterceptorAdapter {
          private final Logger logger = LoggerFactory.getLogger(TestFilter.class);
          @Override
          public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
                  throws Exception {
              logger.info("request请求地址path[{}] uri[{}]", request.getServletPath(),request.getRequestURI());
              //request.getHeader(String) 从请求头中获取数据
              //从请求头中获取用户token(登陆凭证根据业务而定)
              Long userId= getUserId(request.getHeader("H-User-Token"));
              if (userId != null && checkAuth(userId,request.getRequestURI())){
                  return true;
              }
              //这里的异常是我自定义的异常,系统抛出异常后框架捕获异常然后转为统一的格式返回给前端, 其实这里也可以返回false
              throw new FastRuntimeException(20001,"No access");
          }
      
          /**
           * 根据token获取用户ID
           * @param userToken
           * @return
           */
          private Long getUserId(String userToken){
              Long userId = null;
              return userId;
          }
      
          /**
           * 校验用户访问权限
           * @param userId
           * @param requestURI
           * @return
           */
          private boolean checkAuth(Long userId,String requestURI){
              return true;
          }
      
          @Override
          public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                                 ModelAndView modelAndView) throws Exception {}
      
          @Override
          public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
                  throws Exception {}
      }
    • 新建WebAppConfigurer 实现WebMvcConfigurer接口

    其实以前都是继承WebMvcConfigurerAdapter类 不过springBoot2.0以上 WebMvcConfigurerAdapter 方法过时,有两种替代方案:
    1、继承WebMvcConfigurationSupport
    2、实现WebMvcConfigurer
    但是继承WebMvcConfigurationSupport会让Spring-boot对mvc的自动配置失效。根据项目情况选择。现在大多数项目是前后端分离,并没有对静态资源有自动配置的需求所以继承WebMvcConfigurationSupport也未尝不可。

    @Configuration
    public class WebAppConfigurer implements WebMvcConfigurer {
    
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            // 可添加多个
            registry.addInterceptor(new TestFilter()).addPathPatterns("/**");
        }
    
        ....
    }

     

  • 相关阅读:
    201521123093 java 第二周学习总结
    201521123093 java 第一周总结
    Word 2010怎么自动添加文献引用
    动态链接库(dll)文件的动态调用(使用动态链接库,解析Wis文件--测井数据文件的一种)
    open inventor 学习笔记
    井眼轨迹的三次样条插值 (vs + QT + coin3d)
    VS2010 + QT 5 +open inventor 环境配置
    我的第一个项目(人力资源管理之报表管理)
    B-tree 和 B+tree
    mysql count(*)与count(1)的区别
  • 原文地址:https://www.cnblogs.com/a-du/p/10811427.html
Copyright © 2011-2022 走看看