Spring Boot project intercepts and filters, springboot

Source: Internet
Author: User

Spring Boot project intercepts and filters, springboot

I. interceptor and filter

Before talking about Spring boot, let's take a look at the filters and interceptors. The two are similar in terms of functions, but there is a big gap in the specific technical implementation. Before analyzing the differences between the two, we should first understand the concept of AOP. AOP is not a specific technology, but a programming idea. In the process of object-oriented programming, we can easily solve vertical expansion through inheritance and polymorphism. However, for horizontal functions, such as enabling transactions in all service methods or recording logs in a unified manner, object-oriented functions cannot be solved. So AOP-object-oriented programming is actually a supplement to the object-oriented programming idea. The filters and interceptors we are talking about today are specific implementations of Aspect-Oriented Programming. The main differences between the two include the following:

1. The Filter depends on the Servlet container and is part of the Servlet specification. the interceptor exists independently and can be used under any circumstances.

2. The execution of the Filter is completed by the Servlet container callback, while the interceptor is usually executed through dynamic proxy.

3. the lifecycle of the Filter is managed by the Servlet container, while the interceptor can be managed through the IoC container. Therefore, instances of other beans can be obtained through injection and other methods, which makes it easier to use.

Ii. filter configuration

Now we use a filter to record the request execution time. The implementation is as follows:

public class LogCostFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {  long start = System.currentTimeMillis();  filterChain.doFilter(servletRequest,servletResponse);  System.out.println("Execute cost="+(System.currentTimeMillis()-start)); } @Override public void destroy() { }}

The logic of this Code is relatively simple, that is, the time stamp is recorded before the method is executed, then the request is executed through the filter chain, and the execution time is calculated between the returned results. The main requirement is that this class must inherit the Filter class. This is the Servlet specification, which is no different from the previous Web project. However, with the filter class, the previous web project can be configured in web. xml, but the spring boot project does not have the web. xml file. How can I configure it? In Spring boot, we need FilterRegistrationBean to complete the configuration. The implementation process is as follows:

@Configurationpublic class FilterConfig { @Bean public FilterRegistrationBean registFilter() {  FilterRegistrationBean registration = new FilterRegistrationBean();  registration.setFilter(new LogCostFilter());  registration.addUrlPatterns("/*");  registration.setName("LogCostFilter");  registration.setOrder(1);  return registration; }}

This completes the configuration. The options to be configured mainly include instantiate the Filter class, specify the url matching mode, and set the Filter Name and execution sequence. there is no difference in the configuration in xml, but the form is different. Now we can start the server to access any URL:

 

You can see that the above configuration has taken effect. In addition to configuring through FilterRegistrationBean, there is also a more direct method, which can be done directly through annotations:

@WebFilter(urlPatterns = "/*", filterName = "logFilter2")public class LogCostFilter2 implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {  long start = System.currentTimeMillis();  filterChain.doFilter(servletRequest, servletResponse);  System.out.println("LogFilter2 Execute cost=" + (System.currentTimeMillis() - start)); } @Override public void destroy() { }}

Here, you can directly use @ WebFilter to configure the url matching mode and Filter Name. Note that the annotation @ WebFilter is the specification of Servlet3.0 and is not provided by Spring boot. In addition to this annotation, we also need to add another annotation in the configuration class: @ ServletComponetScan, specifying the scan package.

@SpringBootApplication@MapperScan("com.pandy.blog.dao")@ServletComponentScan("com.pandy.blog.filters")public class Application { public static void main(String[] args) throws Exception {  SpringApplication.run(Application.class, args); }}

Now, let's access any URL:

 

We can see that both filters have taken effect. Careful readers will find that we didn't specify the execution sequence for the second Filter, but it was executed before the first Filter. Here we need to explain that the annotation @ WebFilter does not specify the attribute of the execution sequence. The execution sequence depends on the Filter name, which is based on the Filter class name (note that it is not the name of the configured filter) and @ WebFilter has a higher priority than the filter configured in FilterRegistrationBean. If you are interested, you can experiment on your own.

Iii. interceptor Configuration

We have introduced how to configure the filter. Next, let's take a look at how to configure an interceptor. We use the Interceptor to implement the same function above and record the request execution time. First, we implement the interceptor class:

public class LogCostInterceptor implements HandlerInterceptor { long start = System.currentTimeMillis(); @Override public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {  start = System.currentTimeMillis();  return true; } @Override public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {  System.out.println("Interceptor cost="+(System.currentTimeMillis()-start)); } @Override public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception { }}

Here we need to implement the HandlerInterceptor interface, which includes three methods. preHandle is executed before the request is executed, and postHandler is executed after the request is executed, however, it is executed only when the preHandle method returns true. afterCompletion is executed after the view rendering is complete. Similarly, preHandle must return true. This method is usually used to clean up resources. In addition to implementing the above interface, we also need to configure it:

@Configurationpublic class InterceptorConfig extends WebMvcConfigurerAdapter { @Override public void addInterceptors(InterceptorRegistry registry) {  registry.addInterceptor(new LogCostInterceptor()).addPathPatterns("/**");  super.addInterceptors(registry); }}


Here we inherit from webmvcjavaseradapter. Friends who have read the previous article should have seen this class. We used this class When configuring static resource directories. Here we overwrite the addInterceptors method to configure the Interceptor. There are two main configuration items: one is to specify the interceptor and the other is to specify the intercepted URL. Now let's start the system to access any URL:

 

We can see that the same function is implemented through the interceptor. However, it is worth noting that this implementation is actually problematic. Because preHandle and postHandle are two methods, we have to set a shared Variable start to store the start value, however, there will be thread security issues. Of course, we can solve this problem through other methods. For example, we can solve this problem through ThreadLocal. If you are interested, you can implement it on your own. However, we can see that although the interceptor is superior to the filter in many scenarios, the filter is easier to implement than the interceptor in this scenario.

Iv. Summary

This article describes how to configure filters and interceptors Based on Spring boot. Both filters and interceptors belong to the specific implementation of the AOP (Aspect-Oriented Programming) idea. In addition to these two implementations, we have also seen another more flexible AOP implementation technology, that is, Aspect. We can use Aspect to complete more and more powerful functions. I will share this with you later.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.