Integrating the use of spring boot interceptors and filters

Keywords: Java SpringBoot Spring JDK

Springboot

1: Interceptor (interceptor)

Interceptors in Java are objects that dynamically intercept action calls. It depends on the web framework and the spring MVC framework in spring MVC. It is an application of AOP based on java reflection mechanism in implementation. It acts like a filter, but the interceptor can only intercept the Controller request, and cannot intercept other requests that directly access static resources.

The interceptor can intercept the front-end requests, define the interceptor needs to implement the HandlerInterceptor interface, and then rewrite the three methods of preHandle, postHandle and afterCompletion according to the needs.


Author: obsession.
Link: https://juejin.im/post/5e639f33f265da570829f63c
Source: Nuggets
The copyright belongs to the author. For commercial reprint, please contact the author for authorization. For non-commercial reprint, please indicate the source.

/**
 * Interceptor
 *
 * @program: myspringboot
 * @author: syt
 * @create: 2020-03-05 21:11
 */
@Component
@Slf4j
public class MyInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("Front interceptor****");
        //Return true to indicate that the request is passed, and return false to indicate that the request is blocked
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        log.info("Post interceptor****");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        log.info("Interceptor execution complete****");
    }
}

To make your interceptor effective, you need to configure webmvc, customize a configuration class to implement the WebMvcConfigurer interface, and then rewrite the addInterceptors method to add the path to be intercepted, JDK 1.8 was inherited from webmvcconfigureadapter before and then re used the methods. However, JDK 1.8 supports the interface default methods. It is officially defined that webmvcconfigureadapter can be directly implemented without inheriting webmvcconfigureadapter.

**
 * Configure interceptors and filters
 *
 * @program: myspringboot
 * @author: syt
 * @create: 2020-03-05 21:16
 */
@Configuration
public class MyConfig implements WebMvcConfigurer {
    @Autowired
    private MyInterceptor myInterceptor;
    /**
     * Add interceptor
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //ADDPA thpatterns for adding interception rules
        //excludePathPatterns to exclude interception
        /*Interceptor to execute*/
        registry.addInterceptor(myInterceptor).
                addPathPatterns("/**").
                excludePathPatterns("/**/login", "/**/esProductinfo/**");
    }

    /**
     * Solve cross domain problems
     * origin is the protocol, domain name, and port number.
     * URL It consists of protocol, domain name, port and path. If the protocol, domain name and port of the two URL s are all the same,
     * They are of the same origin. Otherwise, as long as there is any difference in protocol, domain name and port, it is cross domain
     *
     * @param registry
     */
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/*")
                .allowedOrigins("*")
                .allowCredentials(true)
                .allowedMethods("GET", "POST", "DELETE", "PUT", "PATCH")
                .maxAge(3600);
    }


}

The custom configuration class can also inherit the WebMvcConfigurationSupport class. This class has many default configurations, but if you inherit the WebMvcConfigurationSupport class, the mvc automatic assembly of SpringBoot will fail. The default configurations need to be defined by yourself, such as the static file address / * *, and you need to add the static file address by adding the resourcehandlers method again

/**
 * Configure interceptors and filters
 *
 * @program: myspringboot
 * @author: syt
 * @create: 2020-03-05 21:16
 */
@Configuration
public class MyConfig extends WebMvcConfigurationSupport {
    @Autowired
    private MyInterceptor myInterceptor;

      /**
     * Static resources
     *
     * @param registry
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
        registry.addResourceHandler("/static/**").addResourceLocations("classpath:/META-INF/resources/static/");
    }

    /**
     * Add interceptor
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //ADDPA thpatterns for adding interception rules
        //excludePathPatterns to exclude interceptions
        /*Interceptor to execute*/
        registry.addInterceptor(myInterceptor).
                addPathPatterns("/**").
                excludePathPatterns("/**/login", "/**/esProductinfo/**");
    }

    /**
     * Solve cross domain problems
     * origin is the protocol, domain name, and port number.
     * URL It consists of protocol, domain name, port and path. If the protocol, domain name and port of the two URL s are all the same,
     * They are of the same origin. Otherwise, as long as there is any difference in protocol, domain name and port, it is cross domain
     *
     * @param registry
     */
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/*")
                .allowedOrigins("*")
                .allowCredentials(true)
                .allowedMethods("GET", "POST", "DELETE", "PUT", "PATCH")
                .maxAge(3600);
    }
}

2: filter

One way

Filter and intercept the request and response of the target resource. Before the request arrives at the servlet, make a logical judgment to determine whether to release it to the servlet; or filter before a response arrives at the client to determine whether to allow it to return to the client.

To define a Filter, you need to implement the Filter interface

@Slf4j
public class MyFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        log.info("MyFilter Of init Method");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        log.info("MyFilter Of doFilter Method");
        //Here you can add a judgment to return your own information when the filter request fails
        if (false) {
            filterChain.doFilter(servletRequest, servletResponse);
            return;
        } else {
            servletResponse.setContentType("text/html;charset=UTF-8;");
            PrintWriter out = servletResponse.getWriter();
            out.write("Filter does not pass");
            log.info("Filter does not pass");
            out.flush();
            out.close();
            return;
        }
    }

    @Override
    public void destroy() {
        log.info("MyFilter Of destroy Method");
    }
}

Configuration is required for the filter to take effect

@Configuration
public class MyConfig{
  
    /**
     * Add filter
     *
     * @return
     */
    @Bean
    public FilterRegistrationBean filterRegistrationBean() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new MyFilter());
        //The default value is false, indicating that the life cycle is managed by SpringApplicationContext, and set to true to indicate that it is managed by ServletContainer
        registration.addInitParameter("targetFilterLifecycle", "true");
        registration.setEnabled(true);
        //The execution order of the filter is small and executed first
        registration.setOrder(1);
        //url path to intercept
        registration.addUrlPatterns("/demand/*", "/notice/*", "/query/*");
        return registration;
    }
}

Mode two

You can directly use the @ WebFilter annotation plus the @ Component annotation to create a filter

@Slf4j
@Component
@WebFilter(filterName = "myFilter",urlPatterns = "/*")
public class MyFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        log.info("MyFilter init method ');
    }

    /**
     * Here's how to filter requests
     */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        log.info("MyFilter Of doFilter Method");
        if (false) {
            filterChain.doFilter(servletRequest, servletResponse);
            return;
        } else {
            servletResponse.setContentType("text/html;charset=UTF-8;");
            PrintWriter out = servletResponse.getWriter();
            out.write("Filter does not pass");
            log.info("Filter does not pass");
            out.flush();
            out.close();
            return;
        }
    }

    @Override
    public void destroy() {
        log.info("MyFilter Of destroy Method");
    }
}

It seems that interceptors and filters are very similar. They can intercept requests and handle them accordingly. Next, let's talk about the specific differences between them.

① : interceptors are java based reflection mechanisms, while filters are based on function callbacks. ② : filters depend on servlet containers, interceptors do not depend on servlet containers. ③ : interceptors only work on action requests, while filters work on almost all requests. ④ : the interceptor can access the action context, the object in the value stack, but the filter cannot. ⑤ : in the life cycle of an action, an interceptor can be called multiple times, while a filter can only be called once when the container is initialized. ⑥ : the interceptor can get the bean s in the IOC container, but the filter can't (inject a service into the interceptor, and call the business logic). ⑦ : the filter is preprocessed after the request enters the container but before it enters the servlet. The response request is also triggered after the servlet processing and before returning to the client. The interceptor provides three methods to support (1) preHandle: preprocessing callback method to realize preprocessing of the processor (such as login check), and the third parameter is the response processor (such as the Controller implementation in our previous chapter); Return value: true means to continue the process (such as calling the next interceptor or processor); false means that the process is interrupted (such as login check failure), and other interceptors or processors will not be called again. At this time, we need to generate a response through response; postHandle: the post-processing callback method, which implements the post-processing of the processor (but before rendering the view). At this time, we can To process model data or view through modelAndView (model and view object), modelAndView may also be null. afterCompletion: the callback method after the whole request is processed, that is, when the view rendering is completed, for example, in performance monitoring, we can record the end time and output the consumption time here, and we can also clean up some resources, similar to finally in try catch finally, but only call the afterCompletion of the interceptor whose preHandle in the execution chain of the processor returns true.

157 original articles published, 45 praised, 100000 visitors+
Private letter follow

Posted by AshtrayWaterloo on Thu, 12 Mar 2020 00:09:26 -0700