1
头图
In the actual project development process, there must be such a demand:
  1. Record the time spent on each rest request, input parameters, and output parameters
  2. Some requests need to be judged whether they have permission, and some requests can be run without permission
This demand is too common. Today we will learn two ways to achieve this requirement together:
  1. Interceptor
  2. filter

Interceptor

Not much to say, let's upload the code and create a new log interceptor:

@Component
public class LogInterceptor implements HandlerInterceptor {
    //在请求rest接口之前调用
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("请求url:"+request.getRequestURL());
        Map<String, String[]> parameterMap = request.getParameterMap();
        Enumeration<String> parameterNames = request.getParameterNames();

        System.out.println("请求参数:");
        while (parameterNames.hasMoreElements()) {
            String name = (String) parameterNames.nextElement();
            String value = request.getParameter(name);
            System.out.println(name+"==>"+value);
        }

        //假设参数a传递的如果是1的话,是不合法的请求,不继续往下执行
        if("1".equals(request.getParameter("a"))){
            return false;
        }
        return true;//如果返回false则不会继续往下执行,不会真正的进入到controller
    }

    //请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle is called...");
    }

    //在整个请求结束之后被调用
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion is called...");
    }
}

Register the interceptor in WebMvcConfigurer spring which paths need to be intercepted and which paths do not need to be intercepted

@Configuration
public class InterceperConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //添加拦截器
        InterceptorRegistration interceptorRegistration = registry.addInterceptor(new LogInterceptor() {
        });
        //如下的路径不拦截,多个路径用逗号分隔
        interceptorRegistration.excludePathPatterns("/demo/test2");
        //拦截如下路径
        interceptorRegistration.addPathPatterns("/**");
    }
}

Well, the interceptor is done, so easy . Let's write a controller to test it!

@RestController
@RequestMapping("/demo")
public class DemoController {

    @GetMapping("test1")
    public String test1(){
        System.out.println("rest.test1 is called");
        return "test1";
    }

    @GetMapping("test2")
    public String test2(){
        System.out.println("rest.test2 is called");
        return "test2";
    }

    @GetMapping("test3")
    public String test3(@RequestParam("a")String a){
        System.out.println("rest.test3 is called");
        return "test3";
    }
}

The results of the test are basically predictable

  1. demo/test1 and demo/test3 will be intercepted and enter the interceptor
  2. demo/test2 will not enter the interceptor
  3. demo/test3?a=1 This request will enter the interceptor, but not the controller.

filter

@WebFilter(urlPatterns = "/*", filterName = "LogFilter")
public class LogFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("logfilter.init is called...");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("filter中打印的请求参数:");
        Enumeration<String> parameterNames = servletRequest.getParameterNames();
        while (parameterNames.hasMoreElements()) {
            String key = parameterNames.nextElement();
            String value = servletRequest.getParameter(key);
            System.out.println(key+"==>"+value);
        }

        long bgn = System.currentTimeMillis();
        //一定要调用链式调用传递,否则也进不了controller
        filterChain.doFilter(servletRequest,servletResponse);
        long end = System.currentTimeMillis();
        System.out.println("filter中记录耗时:"+(end-bgn)+"ms");
    }

    @Override
    public void destroy() {
        System.out.println("logfilter.destroy is called...");
    }
}
Note: @WebFilter this annotation is Servlet3.0 the norm, not the Spring boot provided. In addition to this annotation, we also need to add another annotation to the configuration class: @ServletComponetScan , which specifies the package to be scanned.

to sum up

The execution order of interceptors and filters is that the filter is executed first, and then the interceptor is executed by default.

If there are multiple filters, they will be executed in order of AZ according to the name of the filter. This is because @WebFilter does not support execution order. Of course, you can also solve it by writing a configuration file.

@Configuration
public class WebConfig {

    @Bean
    public FilterRegistrationBean reqResFilter1() {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        LogFilter logFilter = new LogFilter();
        filterRegistrationBean.setFilter(logFilter);
        filterRegistrationBean.addUrlPatterns("/demo/test1","/demo/test3");//配置过滤规则
        filterRegistrationBean.addInitParameter("name","spingboot");//设置init参数
        filterRegistrationBean.setName("logFilter");//设置过滤器名称
        filterRegistrationBean.setOrder(2);//执行次序

        return filterRegistrationBean;
    }

    @Bean
    public FilterRegistrationBean reqResFilter() {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        Log1Filter log1Filter = new Log1Filter();
        filterRegistrationBean.setFilter(log1Filter);
        filterRegistrationBean.addUrlPatterns("*");//配置过滤规则
        filterRegistrationBean.setName("Log1Filter");//设置过滤器名称
        filterRegistrationBean.setOrder(1);//执行次序
        
        return filterRegistrationBean;
    }
}
More java original reading: https://javawu.com/

大盛玩java
24 声望5 粉丝