zoukankan      html  css  js  c++  java
  • 拦截Restful API的三种方式

    如题, 方式有三种。

    (1). 过滤器filter

      javaEE规范

    (2). 拦截器interceptor

      springmvc提供

    (3). 切片 aspect  

    一. Filter使用示例

    import org.springframework.stereotype.Component;
    
    import javax.servlet.*;
    import java.io.IOException;
    
    /**
     * 使用@Component注解,该Filter就生效了。
     * 还可以使用配置方式使用过滤生效 {@link FilterRegistrationBean}
     */
    @Component
    public class LoggerFilter implements Filter {
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            System.out.println("LoggerFilter doFilter begin");
            long startTime = System.currentTimeMillis();
            filterChain.doFilter(servletRequest,servletResponse);
            long endTime = System.currentTimeMillis();
            System.out.println("used time :" + (endTime - startTime));
            System.out.println("LoggerFilter doFilter end");
        }
    
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            System.out.println("LoggerFilter init...");
        }
    
        @Override
        public void destroy() {
            System.out.println("LoggerFilter destroy...");
        }
    }

    二. Interceptor使用示例

    2.1 自定义一个拦截器

    import org.springframework.stereotype.Component;
    import org.springframework.web.method.HandlerMethod;
    import org.springframework.web.servlet.HandlerInterceptor;
    import org.springframework.web.servlet.ModelAndView;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * 定义一个拦截器, 它会拦截所有的控制器,包括spring自带的控制器,诸如BasicErrorController.class
     * 注意: interceptor与filter不同,仅仅使用一个@Component注解,该interceptor并不会生效
     */
    @Component
    public class LoggerInterceptor implements HandlerInterceptor {
        /**
         * 在进入controller方法之前调用
         *
         * @param handler : 就是启用的controller方法
         * @return true: 执行下一个拦截器
         * @throws Exception
         */
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            System.out.println("LoggerInterceptor preHandle...");
            request.setAttribute("startTime", System.currentTimeMillis());
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            System.out.println("Controller类名:"+ handlerMethod.getBean().getClass().getName());
            System.out.println("Controller方法名:"+ handlerMethod.getMethod().getName());
            return true;
        }
    
        /**
         * 在执行完controller方法之后调用,如果controller方法抛出异常,则不会调用
         *
         * @param request
         * @param response
         * @param handler
         * @param modelAndView
         * @throws Exception
         */
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            System.out.println("LoggerInterceptor postHandle begin");
            long startTime = (long) request.getAttribute("startTime");
            System.out.println("used time :" + ( System.currentTimeMillis()-startTime));
            System.out.println("LoggerInterceptor postHandle end");
        }
    
        /**
         * 在视图渲染之后调用,controller有无异常抛出,都会被调用
         * @param  ex  如果controller方法无异常抛出,ex 为null , 否则就是controller中抛出来的异常
         * @throws Exception
         */
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
            System.out.println("LoggerInterceptor afterCompletion begin");
            long startTime = (long) request.getAttribute("startTime");
            System.out.println("used time :" + ( System.currentTimeMillis()-startTime));
            System.out.println("LoggerInterceptor afterCompletion ex = " + ex);
            System.out.println("LoggerInterceptor afterCompletion end");
        }
    }

    2.2 注册拦截器

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    import qinfeng.zheng.mockmvcdemo.interceptor.LoggerInterceptor;
    
    /**
     * SpringBoot 1.X 使用WebMvcConfigurerAdapter.java即可,
     * SpringBoot 2.x WebMvcConfigurerAdapter.java已过时了
     */
    @Configuration
    public class WebConfig implements WebMvcConfigurer {
    
        @Autowired
        private LoggerInterceptor loggerInterceptor;
    
        /**
         * 注册拦截器
         * @param registry
         */
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
    //        registry.addInterceptor(new LoggerInterceptor());
            registry.addInterceptor(loggerInterceptor);
        }
    }

    三. 切片

    /**
     * 定义一个切片
     */
    @Aspect
    @Component
    public class LoggerAspect {
        /**
         * 第一个 * : 方法的任意返回值
         * 第二个 * : qinfeng.zheng.mockmvcdemo.controller.TestController类中的任意方法
         *  ..  : 方法的任意参数
         * @param pjp
         * @return
       *
       * 参考: https://docs.spring.io/spring/docs/5.2.0.RELEASE/spring-framework-reference/core.html#aop   5.4.3
         */
        @Around("execution(* qinfeng.zheng.mockmvcdemo.controller.TestController.*(..))")
        public Object handle(ProceedingJoinPoint pjp) throws Throwable {
            System.out.println("LoggerAspect handle start...");
            // 方法参数列表
            Object[] args = pjp.getArgs();
            Arrays.stream(args).forEach(x-> System.out.println(x));
            long startTime = System.currentTimeMillis();
            Object result = pjp.proceed();
            System.out.println("used time :" + (System.currentTimeMillis() - startTime));
            System.out.println("LoggerAspect handle end...");
            return result;
        }
    }

    四. 总结

      Filter最弱,只能获取request对象

      Interceptor,比Filter好,它不但能获取request对象 ,而且还能拿到HandlerMethoh对象,从而知道调用那个Controller ,以及具体的方法

      Aspect,功能最强大,它可以获取Controller方法的方法的参数列表。。。。。

  • 相关阅读:
    .NET中二进制图片的存储与读取
    mantis基本配置及邮件服务器配置
    搜狗浏览器特性页面JS
    从多个textarea中随机选取一个内容
    JS截取字符串substr 和 substring方法的区别
    MySQL递归的替代方案
    Eclipse去掉对JS文件的Validation
    Hadoop学习笔记二
    es随想二
    Hadoop学习笔记一
  • 原文地址:https://www.cnblogs.com/z-qinfeng/p/11749612.html
Copyright © 2011-2022 走看看