• Springcloud学习笔记39拦截器Interceptor详细使用


    1.拦截器Interceptor定义

    拦截器是在面向切面编程中应用的,就是在你的service或者一个方法前调用一个方法,或者在方法后调用一个方法。是基于JAVA的反射机制。

    1.1 拦截器(Interceptor)执行顺序

    (1)请求到达 DispatcherServlet
    (2)DispatcherServlet 发送至 Interceptor ,执行 preHandle
    (3)请求达到 Controller
    (4)请求结束后,postHandle 执行

     1.2 使用方法

    HandlerInterceptorAdapter 这个适配器是由Spring MVC提供的(org.springframework.web.servlet.handler.HandlerInterceptorAdapter)继承此类,可以非常方便的实现自己的拦截器,而且不仅可实现Filter的所有功能,还可以更精确的控制拦截精度(shiro中的拦截器可以说是基于此实现的)

    public abstract class HandlerInterceptorAdapter implements AsyncHandlerInterceptor {
        public HandlerInterceptorAdapter() {
        }
    
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            //preHandle在业务处理器处理请求之前被调用。预处理,可以进行编码、安全控制等处理;
            return true;
        }
    
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
            //在业务处理器处理请求执行完成后,生成视图之前执行。后处理(调用了Service并返回ModelAndView,但未进行页面渲染),有机会修改ModelAndView;
        }
    
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
            //在DispatcherServlet完全处理完请求后被调用,可用于清理资源等。返回处理(已经渲染了页面),可以根据ex是否为null判断是否发生了异常,进行日志记录;
        }
    
        public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        }
    }

    2.Spring Boot配置方式

    2.1 自定义拦截器,需要继承HandlerInterceptorAdapter类

    具体案例实现如下:

    (1)拦截器AccessLogInterceptor

    @Slf4j
    public class AccessLogInterceptor extends HandlerInterceptorAdapter {
    
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            log.info("进入到拦截器AccessLogInterceptor中:preHandle() 方法");
            String remoteAddr=getRequestIp(request);
            log.info("接收到来自[{}]请求",remoteAddr);
            return true;
        }
    
        private String getRequestIp(HttpServletRequest request) {
            String requestIp = request.getHeader("x-forwarded-for");
            return requestIp;
    
        }
    }

    (2)拦截器AuthorityInterceptor

    @Slf4j
    public class AuthorityInterceptor extends HandlerInterceptorAdapter {
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            log.info("进入到拦截器AuthorityInterceptor中:preHandle() 方法");
            return true;
        }
    }

    2.2 注册拦截器,需要实现WebMvcConfigurer接口

    WebMvcConfigurer配置类其实是Spring内部的一种配置方式,采用JavaBean的形式来代替传统的xml配置文件形式进行针对框架个性化定制,可以自定义一些Handler,Interceptor,ViewResolver,MessageConverter。基于java-based方式的spring mvc配置,需要创建一个配置类并实现WebMvcConfigurer 接口;

    在Spring Boot 1.5版本都是靠重写WebMvcConfigurerAdapter的方法来添加自定义拦截器,消息转换器等。SpringBoot 2.0 后,该类被标记为@Deprecated(弃用)。官方推荐直接实现WebMvcConfigurer。

    WebMvcConfigurer接口代码如下:

    public interface WebMvcConfigurer {
        void configurePathMatch(PathMatchConfigurer var1);
     
        void configureContentNegotiation(ContentNegotiationConfigurer var1);
     
        void configureAsyncSupport(AsyncSupportConfigurer var1);
     
        void configureDefaultServletHandling(DefaultServletHandlerConfigurer var1);
     
        void addFormatters(FormatterRegistry var1);
     
        void addInterceptors(InterceptorRegistry var1);
     
        void addResourceHandlers(ResourceHandlerRegistry var1);
     
        void addCorsMappings(CorsRegistry var1);
     
        void addViewControllers(ViewControllerRegistry var1);
     
        void configureViewResolvers(ViewResolverRegistry var1);
     
        void addArgumentResolvers(List<HandlerMethodArgumentResolver> var1);
     
        void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> var1);
     
        void configureMessageConverters(List<HttpMessageConverter<?>> var1);
     
        void extendMessageConverters(List<HttpMessageConverter<?>> var1);
     
        void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> var1);
     
        void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> var1);
     
        Validator getValidator();
     
        MessageCodesResolver getMessageCodesResolver();
    }

    需要重写addInterceptors方法,这里是对根目录"/"进行拦截,可以指定拦截url请求目录。

    具体案例实现如下:

    @Configuration
    public class MyWebMvcConfigurerAdapter implements WebMvcConfigurer {
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            addV1Rule(registry);
        }
    
        private void addV1Rule(InterceptorRegistry registry) {
            //注册自己的拦截器并设置拦截的请求路径
            registry.addInterceptor(new AccessLogInterceptor()).addPathPatterns("/**");  //拦截所有请求
            registry.addInterceptor(new AuthorityInterceptor()).addPathPatterns("/student/getStudentName");  //拦截student相关请求
    
        }
    }

    2.3 案例测试结果分析

    用户请求的url如下所示:

    @RestController
    @RequestMapping("/student")
    @Slf4j
    public class StudentController {
        @Autowired
        private IStudentService studentService;
    
        @PostMapping("/getStudentName")
        public void getStudentName(){
            log.info("studentName:lucky");
        }
    }

    postman请求的url: http://127.0.0.1:7010/student/getStudentName

    控制台输出:

    2022-01-24 13:47:15.599 |  INFO  | http-nio-7010-exec-1 | com.ttbank.flep.core.interceptor.AccessLogInterceptor:18 | [] -进入到拦截器AccessLogInterceptor中:preHandle() 方法
    2022-01-24 13:47:15.600 |  INFO  | http-nio-7010-exec-1 | com.ttbank.flep.core.interceptor.AccessLogInterceptor:20 | [] -接收到来自[11112222]请求
    2022-01-24 13:47:15.600 |  INFO  | http-nio-7010-exec-1 | com.ttbank.flep.core.interceptor.AuthorityInterceptor:17 | [] -进入到拦截器AuthorityInterceptor中:preHandle() 方法
    2022-01-24 13:47:15.605 |  INFO  | http-nio-7010-exec-1 | com.ttbank.flep.core.controller.StudentController:41 | [] -studentName:lucky

    参考文献:

    https://blog.csdn.net/zhangpower1993/article/details/89016503

    https://blog.csdn.net/kuishao1314aa/article/details/109777304

  • 相关阅读:
    HDOJ2553 N皇后问题
    NYOJ284 坦克大战 BFS/优先队列
    NYOJ14 会场安排问题 贪心
    POJ1664 放苹果
    NYOJ119 士兵杀敌(三) RMQ
    POJ3264 Balanced Lineup RMQ/线段树
    POJ1127 Jack Straws
    HDOJ1128 Self Numbers
    水晶报表CrystalReports很强大也很简单!
    PetShop项目学习笔记(三)
  • 原文地址:https://www.cnblogs.com/luckyplj/p/15839125.html
Copyright © 2020-2023  润新知