• Spring 梳理


    前言

    项目中我们经常需要对RESTful api进行拦截,主流实现方法有filter、interceptor、aop,先说一下他们各自的实现。

    Filter

    AnimalFilter实现javax.servlet.Filter,项目启动时已初始化完成,可在控制台看到打印的初始化日志。

        @Component
        public class AnimalFilter implements Filter {
         
            private Logger logger = LoggerFactory.getLogger(getClass());
         
            @Override
            public void init(FilterConfig filterConfig) throws ServletException {
                logger.info("animalFilter 初始化。。。");
            }
         
            @Override
            public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
                logger.info("animalFilter doFilter 。。。");
                chain.doFilter(request,response);//过滤器将请求往下传递
            }
         
            @Override
            public void destroy() {
                logger.info("animalFilter 销毁。。。");
            }
        }

    如何调用不被component修饰的filter,将上文中的component注解去除,通过下文方式,让注解生效并设置注解生效的url请求地址信息。

        @Configuration
        public class AnimalWebConfig {
         
            @Bean
            public FilterRegistrationBean animalFilter(){
                FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
                AnimalFilter animalFilter = new AnimalFilter();
                filterRegistrationBean.setFilter(animalFilter);
                List<String> urlPattern = new ArrayList<>();
                urlPattern.add("/animal/getAnimalById/*");
                filterRegistrationBean.setUrlPatterns(urlPattern);
                return filterRegistrationBean;
            }
         
        }

    由于filter获取的参数为ServletRequest request, ServletResponse response, FilterChain chain,无法知道是哪个类的那个方法调用,更无法知道调用时的参数。

    Interceptor

    首先编写一个AnimalInterceptor实现HandlerInteceptor方法,实现相应的三个方法,preHandle执行方法前执行返回的结果决定是否往下执行,postHandle当方法返回值时执行,afterCompletion无论成功或失败都将执行,前提是preHandler要返回true。

        @Component
        public class AnimalInterceptor implements HandlerInterceptor {
         
            private Logger logger = LoggerFactory.getLogger(getClass());
         
            @Override
            public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
                HandlerMethod handlerMethod = (HandlerMethod) handler;
                String methodName = handlerMethod.getMethod().getName();
                logger.info("AnimalInterceptor:preHandle:methodName:" + methodName);
                logger.info("AnimalInterceptor:preHandle");
                return true;
            }
         
            @Override
            public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
                HandlerMethod handlerMethod = (HandlerMethod) handler;
                logger.info("AnimalInterceptor:preHandle:methodName:" + handlerMethod.getMethod().getName());
                logger.info("AnimalInterceptor:postHandle");
            }
         
            @Override
            public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
                logger.info("AnimalInterceptor:afterCompletion");
            }
        }

    将写好的AnimalInterceptor注入到spring的interceptor注册中心即可

        @Component
        public class InterceptorConfig extends WebMvcConfigurerAdapter{
         
            @Autowired
            AnimalInterceptor animalInterceptor;
         
            @Override
            public void addInterceptors(InterceptorRegistry registry) {
                registry.addInterceptor(animalInterceptor);
            }
        }

    虽然interceptor可以知道调用的controller,调用的方法,但获取不到调用方法的参数。

    AOP

    编写AnimalAspect如下,可将传递的参数打印出来,aop拦截规则设置请查看,https://blog.csdn.net/FU250/article/details/80219415

        @Aspect
        @Component
        public class AnimalAspect {
            private Logger logger = LoggerFactory.getLogger(getClass());
         
            @Around("execution(* com.imooc.security.demo.web.controller..*.*(..))")
            public Object handleAnimalController(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
                Arrays.stream(proceedingJoinPoint.getArgs()).forEach(arg -> {
                    logger.info("arg:"+arg);
                });
                logger.info("AnimalAspect");
                return proceedingJoinPoint.proceed();
            }
        }

    三个拦截器的比较如下,根据自己的业务功能需求选择最合适的拦截器。



       

  • 相关阅读:
    Lua中如何实现类似gdb的断点调试—06断点行号检查与自动修正
    211. 添加与搜索单词 数据结构设计 (JAVA)
    SuperSocket 1.5 stable发布
    SuperWebSocket发布0.1版本
    无需等待,SuperSocket 1.4 SP1 发布了!
    SuperSocket 1.5 文档列表
    SuperSocket 1.4 SP2 发布了!
    imx6ull spiimx.c 驱动接收导致内存问题
    nacos下载、安装、使用,SpringCloud、SpringBoot、SpringCloudAlibaba版本匹配、openfeign、loadbalancer、nacos配置中心
    idea配置显示Run Dashboard,引入自定义jar包
  • 原文地址:https://www.cnblogs.com/jiangtao1218/p/10241835.html
Copyright © 2020-2023  润新知