Article directory
Filter belongs to the Servlet specification, not unique to Spring. Filter is mainly used to intercept requests, do some business logic operations, and then decide whether the request can continue to be distributed to other Filters or corresponding Servlets.
Filter workflow
-
Enter filter and execute relevant business logic
-
If the judgment fails, return directly without sending the request to the Servlet
-
If it is determined to pass, proceed to the next filter
If all filters pass, enter the Servlet logic, after the Servlet is executed, return to Filter, and finally return to the requester
How to use custom Filter
The different usage methods of the filter in Spring are all through: FilterRegistrationBean wraps the filter and finally registers it in the Servlet container.
1. @WebFilter+@ServletComponentScan
Add the @ServletComponentScan annotation on SpringBootApplication and the @WebFilter annotation on Filter.
Disadvantages of this method: the priority between filters cannot be set.
The @WebFilter+@ServletComponentScan method cannot specify the filter priority through the @Order annotation: the priority uses the default value Ordered.LOWEST_PRECEDENCE (2147483647). In the case of the same priority, it is determined according to the order of the names.
Instructions
1. Use the @ServletComponentScan annotation on SpringBootApplication
@ServletComponentScan
@SpringBootApplication
public class SpringbootApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootApplication.class, args);
}
}
2. Use @WebFilter annotation on Filter
@WebFilter(urlPatterns = {
"/test3"})
public class MyFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
System.out.println("======= MyFilter =======");
filterChain.doFilter(request,response);
}
}
@WebFilter
@WebFilter is used to declare a class as a filter.
The main attributes of the WebFilter annotation:
attribute name | type | describe |
---|---|---|
filterName | String | Specify the name attribute of the filter (springbean also uses this name), which is equivalent to <filter-name> |
urlPatterns | String[] | Specifies a set of URL matching patterns for filters. Equivalent to <url-pattern> |
value | String[] | This attribute is equivalent to the urlPatterns attribute, but both should not be used at the same time |
sevletNames | String[] | Specifies which servlets the filter will be used for. The value is the value of the name attribute in @WebServlet, or <servlet-name> in web.xml |
dispatcherTypes | DispatcherType[] | Specifies the forwarding mode for a set of filters. Specific values include: ASYNC, ERROR, FORWARD, INCLUDE, REQUEST, default REQUEST |
initParams | WebInitParam[] | Specify a set of filter initialization parameters, equivalent to <init-param> |
asyncSupported | boolean | Declare whether the filter supports asynchronous operation mode, equivalent to the <async-supported> tag |
description | String | Description of the filter, equivalent to <description> |
displayName | String | The display name of the filter, usually used with tools, is equivalent to <display-name> |
@ServletComponentScan
In the SpringBoot project, the three annotations @WebServlet, @WebFilter, and @WebListener are not scanned by default. Generally, the @ServletComponentScan annotation is added to SpringBootApplication to indicate the scanning of these three annotations.
@ServletComponentScan can automatically register Servlet (controller), Filter (filter), and Listener (listener) into the Spring container without additional code.
- Servlet: defined by @WebServlet annotation
- Filter: defined by @WebFilter annotation
- Listener: defined by @WebListener annotation
FAQ analysis
1. Only use @WebFilte: the filter does not take effect
WebFilter belongs to annotation and belongs to Servlet3+, and has nothing to do with Spring itself, so Spring does not recognize this annotation by default.
2. @WebFilter+@Component: The configured filter condition does not take effect
Same as above, Spring does not recognize the @WebFilter annotation, so any attribute of the annotation configuration is meaningless (for example: specifying the url to filter).
This method is actually equivalent to only adding a @Component annotation. At this time, the filter can take effect, but there is no filter condition, and all urls will be filtered.
3. @WebFilter+@Component+@ServletComponentScan: The filter will be called twice
- Once: @WebFilter+@ServletComponentScan, managed by SpringBean, the filter takes effect, and filters according to the attributes configured by @WebFilter
- Second time: @Component is managed by SpringBean again, the filter takes effect (not the same bean as above), and all urls are filtered
4. @WebFilter+@Order+@ServletComponentScan: setting filter priority is invalid
Registered through @WebFilter+@ServletComponentScan, the generated FilterRegistrationBean does not check the @Order annotation, so the @Order annotation does not take effect.
For details, please refer to the article: Regarding the invalid use of @Order by @webFilter
2. @Component+@Order
By adding @Component and @Order annotations to the Filter, it can be managed by Spring, and the execution order of the filter can be specified.
Disadvantages of this method: only all URLs can be filtered, and specified URLs cannot be filtered through configuration.
Instructions
@Order(100)
@Component
public class MyFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
System.out.println("======= MyFilter =======");
filterChain.doFilter(request,response);
}
}
3. FilterRegistrationBean (recommended)
Define the FilterRegistrationBean of the Filter directly through the configuration class, and hand it over to the SpringBean container for management.
This method can not only filter the specified URL through configuration, but also specify the priority between filters.
Instructions
public class MyFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
System.out.println("======= MyFilter =======");
filterChain.doFilter(request,response);
}
}
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean<MyFilter> filterRegistrationBean() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(myFilter());
registration.setName("myFilter");
registration.addUrlPatterns("/test3");
registration.setOrder(100);
return registration;
}
@Bean
public MyFilter myFilter() {
return new MyFilter();
}
}