In the actual project development process, there must be such requirements:

  1. Log the time spent on each REST request, in and out
  2. Some requests need to be checked for permissions, and some requests can run without permissions

This need is all too common. Today we will look at two ways to implement this requirement:

  1. The interceptor
  2. The filter

The interceptor

Without further ado, let’s go to code and create a new log interceptor:

@Component
public class LogInterceptor implements HandlerInterceptor {
    // called before requesting the REST interface
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("Request URL:"+request.getRequestURL());
        Map<String, String[]> parameterMap = request.getParameterMap();
        Enumeration<String> parameterNames = request.getParameterNames();

        System.out.println("Request parameters:);
        while (parameterNames.hasMoreElements()) {
            String name = (String) parameterNames.nextElement();
            String value = request.getParameter(name);
            System.out.println(name+"= = >"+value);
        }

        // If a is passed with a value of 1, it is an invalid request and does not proceed
        if("1".equals(request.getParameter("a"))) {return false;
        }
        return true;// If false is returned, it will not proceed and will not actually enter the controller
    }

    // Call after request processing, but before the view is rendered (after Controller method call)
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle is called...");
    }

    // is called after the entire request ends
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion is called..."); }}Copy the code

Register the interceptor in WebMvcConfigurer and tell Spring which paths to intercept and which paths not to intercept

@Configuration
public class InterceperConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // Add interceptor
        InterceptorRegistration interceptorRegistration = registry.addInterceptor(new LogInterceptor() {
        });
        // The following paths are not intercepted. Multiple paths are separated by commas
        interceptorRegistration.excludePathPatterns("/demo/test2");
        // Intercept the following path
        interceptorRegistration.addPathPatterns("/ * *"); }}Copy the code

All right, we’re done with the interceptor, so easy. Now let’s write a controller to test it!

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

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

    @GetMapping("test2")
    public String test2(a){
        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"; }}Copy the code

The results of the test were largely predictable

  1. Demo /test1 and Demo /test3 will be blocked by interceptors
  2. Demo/Test2 will not enter interceptors
  3. demo/test3? A =1 will go into the interceptor, but not into the Controller.

The 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("Request parameters printed in 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();
        // You must call the chained call pass, otherwise you will not enter the controller
        filterChain.doFilter(servletRequest,servletResponse);
        long end = System.currentTimeMillis();
        System.out.println("Time recorded in filter:"+(end-bgn)+"ms");
    }

    @Override
    public void destroy(a) {
        System.out.println("logfilter.destroy is called..."); }}Copy the code

Note: the @webfilter annotation is a Servlet3.0 specification, not provided by Spring boot. In addition to this annotation, we need to add another annotation to the configuration class: @ServletComponetScan, which specifies the package to scan.

conclusion

Interceptor/filter execution order. By default, filter is executed before interceptor.

If there are multiple filters, they are executed in an a-Z order based on the filter name. This is because the @webfilter annotation does not support execution order. You can also do this by writing a configuration file.

@Configuration
public class WebConfig {

    @Bean
    public FilterRegistrationBean reqResFilter1(a) {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        LogFilter logFilter = new LogFilter();
        filterRegistrationBean.setFilter(logFilter);
        filterRegistrationBean.addUrlPatterns("/demo/test1"."/demo/test3");// Configure filtering rules
        filterRegistrationBean.addInitParameter("name"."spingboot");// Set the init parameter
        filterRegistrationBean.setName("logFilter");// Set the filter name
        filterRegistrationBean.setOrder(2);// Order of execution

        return filterRegistrationBean;
    }

    @Bean
    public FilterRegistrationBean reqResFilter(a) {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        Log1Filter log1Filter = new Log1Filter();
        filterRegistrationBean.setFilter(log1Filter);
        filterRegistrationBean.addUrlPatterns("*");// Configure filtering rules
        filterRegistrationBean.setName("Log1Filter");// Set the filter name
        filterRegistrationBean.setOrder(1);// Order of execution
        
        returnfilterRegistrationBean; }}Copy the code

More original Java reading: javawu.com/