zoukankan      html  css  js  c++  java
  • 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();
            }
        }

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



       

  • 相关阅读:
    odoo字段
    页签中加按钮 odoo里面
    页签类型按钮上面记录条数获得
    sql语句 这里是取一串数据中的 头 中 尾 几个数据
    python 字典,元组,对象,数组取值方法
    action类型的按钮和object按钮的用法
    数据结构与算法 基于c语言篇
    odoo开发历史订单需求整体思路
    spring框架的ioc和aop
    java注解和反射学习
  • 原文地址:https://www.cnblogs.com/jiangtao1218/p/10241835.html
Copyright © 2011-2022 走看看