concept
Filter is one of the three components of JavaWeb. The three components are Sevlet, Filter and Listener. Filter is a JavaEE specification, that is, an interface. It is used to block requests and filter responses. Its common application scenarios include: authentication permission check, logging, and so on.
The working process
Using the step
We now mostly use Spring Boot for Web development, not Sevlet. Let’s do this in the Spring Boot environment. Suppose you now need to implement a requirement to record the elapsed time of an interface. The implementation is as follows:
@RestController public class TestController { private static final Logger logger = LoggerFactory.getLogger(TestController.class); @RequestMapping(value = "/test") public void test() throws InterruptedException { Thread.sleep(5000); Logger. info(" Access successful "); }}Copy the code
Write a Controller request test
public class RecordFilter implements Filter { private static final Logger logger = LoggerFactory.getLogger(RecordFilter.class); @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain FilterChain) throws IOException, ServletException {logger.info(" Enter RecordFilter"); long start = System.currentTimeMillis(); filterChain.doFilter(servletRequest, servletResponse); Logger. info(" Execute interface time: {}", (system.currentTimemillis () -start)); }}Copy the code
Write a class to implement the Filter interface, implement the Filter method doFilter(), configure the interception path of the custom Filter, we in JSP era is to configure in web. XML, but the Spring Boot project does not have the web. We need the FilterRegistrationBean to complete the configuration. The implementation is as follows:
@Configuration public class FilterConfig { @Bean public FilterRegistrationBean registerFilter() { FilterRegistrationBean registration = new FilterRegistrationBean(); // Set the filter registration.setFilter(new RecordFilter()); / / configure interceptor path registration. AddUrlPatterns (" / * "); // Set the filter name registration.setName("RecordFilter"); // Set the execution order registration.setOrder(1); return registration; }}Copy the code
This is no different from web.xml, just in a different form. Of course, we can also choose to configure the filter based on annotations, which can be added to the name of the filter class we just defined, without creating a new class. You can choose either way.
@Order(1) @WebFilter(filterName="recordFilter", urlPatterns="/*") @Configuration public class RecordFilter implements Filter { private static final Logger logger = LoggerFactory.getLogger(RecordFilter.class); @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain FilterChain) throws IOException, ServletException {logger.info(" Enter RecordFilter"); long start = System.currentTimeMillis(); filterChain.doFilter(servletRequest, servletResponse); Logger. info(" Execute interface time: {}", (system.currentTimemillis () -start)); }}Copy the code
The life cycle
The Filter lifecycle consists of the following methods
- Constructor method
- Init initialization method: Executed when the Web project starts
- DoFilter method: Intercepts request execution
- Destory destruction: Executed when the Web project stops
The FilterConfig class
The FilterConfig class is the configuration file class for filters. Each time Tomcat creates a Filter, it also creates a FilterConfig class, which contains the configuration information of the Filter configuration file.
The FilterConfig class is used to get the configuration of the filter
- Gets the name of Filter
- Initialization parameters specified in Filter in the past
- Get the ServletContext object
FilterChain FilterChain
FilterChain is a chain of filters. Multiple filters work together. Spring Security, our commonly used authentication and authorization framework, is based on the FilterChain. The following shows the steps to execute multiple filters
@Order(1) @WebFilter(filterName="filterA", urlPatterns="/*") @Configuration public class FilterA implements Filter { private static final Logger logger = LoggerFactory.getLogger(FilterA.class); @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain FilterChain) throws IOException, ServletException {logger.info(" Enter FilterA start "); filterChain.doFilter(servletRequest, servletResponse); Logger. info(" Enter FilterA end "); }}Copy the code
@Order(2) @WebFilter(filterName="filterB", urlPatterns="/*") @Configuration public class FilterB implements Filter { private static final Logger logger = LoggerFactory.getLogger(FilterB.class); @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain FilterChain) throws IOException, ServletException {logger.info(" Enter FilterB to start "); filterChain.doFilter(servletRequest, servletResponse); Logger. info(" enter FilterB end "); }}Copy the code
@RestController public class TestController { private static final Logger logger = LoggerFactory.getLogger(TestController.class); @requestMapping (value = "/test") public void test() throws InterruptedException {logger.info(" Access successful "); }}Copy the code
Access log
From this, we can see the working flow of multiple filters as follows:
The function of the filterchain-dofilter () method
- If a filter still exists, the next filter is executed.
- If no filter exists, execute the target resource;
Multiple Filter Filter execution characteristics
- All filters and target resources execute in the same thread;
- When multiple filters are executed together, they all use the same request object.