Spring Boot中是否有Filter类(用于web应用程序)的注释?也许@Filter ?
我想在我的项目中添加一个自定义过滤器。
Spring Boot参考指南中提到过 FilterRegistrationBean,但我不确定如何使用它。
Spring Boot中是否有Filter类(用于web应用程序)的注释?也许@Filter ?
我想在我的项目中添加一个自定义过滤器。
Spring Boot参考指南中提到过 FilterRegistrationBean,但我不确定如何使用它。
当前回答
使用Spring注册过滤器大约有四种不同的选项。
首先,我们可以创建一个实现Filter或扩展HttpFilter的Spring bean:
@Component
public class MyFilter extends HttpFilter {
@Override
protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws IOException, ServletException {
// Implementation details...
chain.doFilter(request, response);
}
}
其次,我们可以创建一个扩展GenericFilterBean的Spring bean:
@Component
public class MyFilter extends GenericFilterBean {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
throws IOException, ServletException {
//Implementation details...
chain.doFilter(currentRequest, servletResponse);
}
}
我们也可以使用FilterRegistrationBean类:
@Configuration
public class FilterConfiguration {
private final MyFilter myFilter;
@Autowired
public FilterConfiguration(MyFilter myFilter) {
this.myFilter = myFilter;
}
@Bean
public FilterRegistrationBean<MyFilter> myFilterRegistration() {
FilterRegistrationBean<DateLoggingFilter> filterRegistrationBean = new FilterRegistrationBean<>();
filterRegistrationBean.setFilter(myFilter);
filterRegistrationBean.setUrlPatterns(Collections.singletonList("/*"));
filterRegistrationBean.setDispatcherTypes(DispatcherType.REQUEST);
filterRegistrationBean.setOrder(Ordered.LOWEST_PRECEDENCE - 1);
return filterRegistrationBean;
}
}
最后,我们可以使用@ServletComponentScan的@WebFilter注释:
@WebFilter(urlPatterns = "/*", dispatcherTypes = {DispatcherType.REQUEST})
public class MyFilter extends HttpFilter {
@Override
protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws IOException, ServletException {
// Implementation details...
chain.doFilter(request, response);
}
}
其他回答
首先,将@ServletComponentScan添加到SpringBootApplication类中。
@ServletComponentScan
public class Application {
其次,创建一个过滤器文件,扩展filter或第三方过滤器类,并像这样添加@WebFilter到这个文件:
@Order(1) //optional
@WebFilter(filterName = "XXXFilter", urlPatterns = "/*",
dispatcherTypes = {DispatcherType.REQUEST, DispatcherType.FORWARD},
initParams = {@WebInitParam(name = "confPath", value = "classpath:/xxx.xml")})
public class XXXFilter extends Filter{
Use:
@WebFilter(urlPatterns="/*")
public class XSSFilter implements Filter {
private static final org.apache.log4j.Logger LOGGER = LogManager.getLogger(XSSFilter.class);
@Override
public void init(FilterConfig filterConfig) throws ServletException {
LOGGER.info("Initiating XSSFilter... ");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpRequestWrapper requestWrapper = new HttpRequestWrapper(req);
chain.doFilter(requestWrapper, response);
}
@Override
public void destroy() {
LOGGER.info("Destroying XSSFilter... ");
}
}
你需要实现Filter,并且它需要用@WebFilter(urlPatterns="/*")进行注释。
在Application或Configuration类中,您需要添加@ServletComponentScan。通过此操作,您的筛选器将被注册。
没有特殊的注释来表示servlet筛选器。您只需声明一个Filter类型的@Bean(或FilterRegistrationBean)。在Boot自己的EndpointWebMvcAutoConfiguration中有一个例子(为所有响应添加自定义头);
如果你只声明一个过滤器,它将被应用到所有的请求。如果您还添加了一个FilterRegistrationBean,您可以另外指定要应用的单个servlet和url模式。
注意:
从Spring Boot 1.4开始,FilterRegistrationBean不再弃用,而是简单地将包从org.springframework. Boot .context. embedd.filterregistrationbean移动到org.springframework.boot.web.servlet.FilterRegistrationBean
如果您使用Spring Boot + Spring Security,则可以在安全配置中执行此操作。
在下面的示例中,我在UsernamePasswordAuthenticationFilter之前添加了一个自定义过滤器(请参阅所有默认的Spring安全过滤器及其顺序)。
@EnableWebSecurity
class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired FilterDependency filterDependency;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.addFilterBefore(
new MyFilter(filterDependency),
UsernamePasswordAuthenticationFilter.class);
}
}
还有筛选器类
class MyFilter extends OncePerRequestFilter {
private final FilterDependency filterDependency;
public MyFilter(FilterDependency filterDependency) {
this.filterDependency = filterDependency;
}
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain)
throws ServletException, IOException {
// Filter
filterChain.doFilter(request, response);
}
}
添加过滤器有三种方法,
用一个Spring原型(如@Component)注释你的过滤器 在Spring @Configuration中注册一个Filter类型的@Bean 在Spring @Configuration中用FilterRegistrationBean类型注册一个@Bean
Either #1 or #2 will do if you want your filter applies to all requests without customization, use #3 otherwise. You don't need to specify component scan for #1 to work as long as you place your filter class in the same or sub-package of your SpringApplication class. For #3, use along with #2 is only necessary when you want Spring to manage your filter class such as have it auto wired dependencies. It works just fine for me to new my filter which doesn't need any dependency autowiring/injection.
虽然结合#2和#3效果很好,但我很惊讶它最终没有应用两次两个过滤器。我的猜测是,当Spring调用相同的方法来创建这两个bean时,它将这两个bean合并为一个。如果您想单独使用#3和authwiring,您可以使用AutowireCapableBeanFactory。举例如下:
private @Autowired AutowireCapableBeanFactory beanFactory;
@Bean
public FilterRegistrationBean myFilter() {
FilterRegistrationBean registration = new FilterRegistrationBean();
Filter myFilter = new MyFilter();
beanFactory.autowireBean(myFilter);
registration.setFilter(myFilter);
registration.addUrlPatterns("/myfilterpath/*");
return registration;
}