Spring Boot中是否有Filter类(用于web应用程序)的注释?也许@Filter ?
我想在我的项目中添加一个自定义过滤器。
Spring Boot参考指南中提到过 FilterRegistrationBean,但我不确定如何使用它。
Spring Boot中是否有Filter类(用于web应用程序)的注释?也许@Filter ?
我想在我的项目中添加一个自定义过滤器。
Spring Boot参考指南中提到过 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文档中,
嵌入式servlet容器——向应用程序中添加servlet、过滤器或监听器
要添加Servlet、过滤器或Servlet *监听器,请提供@Bean 定义。
例如:
@Bean
public Filter compressFilter() {
CompressingFilter compressFilter = new CompressingFilter();
return compressFilter;
}
将这个@Bean配置添加到@Configuration类中,过滤器将在启动时注册。
此外,您还可以使用类路径扫描添加servlet、过滤器和侦听器,
@WebServlet, @WebFilter和@WebListener注释类可以是 自动注册到嵌入的servlet容器 用@ServletComponentScan和注释@Configuration类 指定包含所需组件的包 登记。默认情况下,@ServletComponentScan将从包中扫描 注释类的。
使用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);
}
}
使用@WebFilter注释,可以这样做:
@WebFilter(urlPatterns = {"/*" })
public class AuthenticationFilter implements Filter{
private static Logger logger = Logger.getLogger(AuthenticationFilter.class);
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest arg0, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
logger.info("checking client id in filter");
HttpServletRequest request = (HttpServletRequest) arg0;
String clientId = request.getHeader("clientId");
if (StringUtils.isNotEmpty(clientId)) {
chain.doFilter(request, response);
} else {
logger.error("client id missing.");
}
}
@Override
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
}
众所周知,Spring Boot是开发web应用程序或独立应用程序的一种极好的方式,具有最低的配置和独立的设置。
这就是我如何在Spring Boot应用程序中实现web过滤器开发的
我的SpringBootApp规格:
Spring Boot版本:2.0.4.RELEASE Java版本:8.0 Servlet规范:Servlet 3.0(强制性和重要)
我以以下方式声明了我的web过滤器,遵循Servlet规范3.0
这是定义过滤器作为基于web.xml定义的替代品的编程方式。
“@Webfilter”注释将在部署期间由容器处理。它所在的Filter类将根据配置创建,并应用于URL模式javax.servlet.Servlets和javax.servlet.DispatcherTypes。
要完全避免Web.xml,实现“可部署”的WebApp:
要将SpringBoot应用程序部署为“Traditional WAR”,应用程序类应该扩展SpringBootServletInitializer。
注意:
SpringBootServletInitializer是web.xml的“编程实现”,参考了Servlet 3.0+规范,它需要WebApplicationInitializer的实现。
因此,SpringBootApplication不需要“web.xml”作为它的应用程序类(在扩展SpringBootServletInitializer之后)。它扫描
@WebFilter, @WebListener鸭 @WebServlet。
注释@ServletComponentScan
这个注释允许扫描带有@WebFilter, @WebListener和@WebServlet注释的web组件的基本包。
由于嵌入式容器不支持@WebServlet、@WebFilter和@WebListener注解,Spring Boot在很大程度上依赖于嵌入式容器,引入了这个新的注解@ServletComponentScan来支持一些使用这三种注解的依赖JAR文件。
扫描只在使用嵌入式Servlet容器时执行。
下面是我的Spring Boot应用程序类定义:
自定义Servlet初始化器:
这里:我定义了一个自定义类:“ServletInitializer”,它扩展了class: SpringBootServletInitializer。
如前所述,SpringBootServletInitializer负责扫描注释:
@WebFilter, @WebListener鸭 @WebServlet。
因此Spring Boot应用程序类应该这样做
扩展类:SpringBootServletInitializer或 扩展扩展该类的自定义类:SpringBootServletInitializer
添加过滤器有三种方法,
用一个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;
}