Spring Boot中是否有Filter类(用于web应用程序)的注释?也许@Filter ?
我想在我的项目中添加一个自定义过滤器。
Spring Boot参考指南中提到过 FilterRegistrationBean,但我不确定如何使用它。
Spring Boot中是否有Filter类(用于web应用程序)的注释?也许@Filter ?
我想在我的项目中添加一个自定义过滤器。
Spring Boot参考指南中提到过 FilterRegistrationBean,但我不确定如何使用它。
当前回答
你可以在实现javax.servlet.Filter的类上使用@WebFilter javax.servlet.annotation.WebFilter:
@WebFilter(urlPatterns = "/*")
public class MyFilter implements Filter {
}
然后使用@ServletComponentScan注册。
其他回答
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。通过此操作,您的筛选器将被注册。
过滤器,顾名思义,用于对资源的请求或资源的响应执行过滤,或同时对两者执行过滤。Spring Boot提供了一些选项来在Spring Boot应用程序中注册自定义过滤器。让我们看看不同的选项。
1. 定义Spring Boot过滤器和调用顺序
实现Filter接口,在Spring Boot中创建一个新的过滤器。
@Configuration
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CustomFilter implements Filter {
private static final Logger LOGGER = LoggerFactory.getLogger(CustomFilter.class);
@Override
public void init(FilterConfig filterConfig) throws ServletException {
LOGGER.info("########## Initiating Custom filter ##########");
}
@Override
public void doFilter(ServletRequest servletRequest,
ServletResponse servletResponse,
FilterChain filterChain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
LOGGER.info("Logging Request {} : {}", request.getMethod(), request.getRequestURI());
// Call next filter in the filter chain
filterChain.doFilter(request, response);
LOGGER.info("Logging Response :{}", response.getContentType());
}
@Override
public void destroy() {
// TODO: 7/4/2018
}
}
让我们快速看一下上面代码中的一些要点
@Component注释注册的过滤器。 为了以正确的顺序触发过滤器,我们需要使用@Order注释。 @ component @Order (1) 公共类CustomFirstFilter实现了Filter { } @ component @Order (2) 公共类CustomSecondFilter实现了Filter { }
在上面的代码中,CustomFirstFilter将在CustomSecondFilter之前运行。
数字越低,优先级越高
2. URL模式
如果基于约定的映射不够灵活,我们可以使用FilterRegistrationBean对应用程序进行完全控制。在这里,不要为过滤器类使用@Component注释,而是使用FilterRegistrationBean注册过滤器。
public class CustomURLFilter implements Filter {
private static final Logger LOGGER = LoggerFactory.getLogger(CustomURLFilter.class);
@Override
public void init(FilterConfig filterConfig) throws ServletException {
LOGGER.info("########## Initiating CustomURLFilter filter ##########");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
LOGGER.info("This Filter is only called when request is mapped for /customer resource");
// Call the next filter in the filter chain
filterChain.doFilter(request, response);
}
@Override
public void destroy() {
}
}
使用FilterRegistrationBean注册自定义过滤器。
@Configuration
public class AppConfig {
@Bean
public FilterRegistrationBean < CustomURLFilter > filterRegistrationBean() {
FilterRegistrationBean < CustomURLFilter > registrationBean = new FilterRegistrationBean();
CustomURLFilter customURLFilter = new CustomURLFilter();
registrationBean.setFilter(customURLFilter);
registrationBean.addUrlPatterns("/greeting/*");
registrationBean.setOrder(2); // Set precedence
return registrationBean;
}
}
你主要需要两样东西:
Add @ServletComponentScan to your Main Class You may add a package named filter inside it. You create a Filter class that has the following: @Component @Order(Ordered.HIGHEST_PRECEDENCE) public class RequestFilter implements Filter { // whatever field you have public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) { HttpServletResponse response = (HttpServletResponse) res; HttpServletRequest request = (HttpServletRequest) req; // Whatever implementation you want try { chain.doFilter(req, res); } catch(Exception e) { e.printStackTrace(); } } public void init(FilterConfig filterConfig) { } public void destroy() { } }
添加过滤器有三种方法,
用一个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;
}
我看到Vasily Komarov的答案。这里有一个类似的方法,但是使用抽象的HandlerInterceptorAdapter类而不是使用HandlerInterceptor。
这里有一个例子……
@Component
public class CustomInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
}
}
@Configuration
public class InterceptorConfig extends WebMvcConfigurerAdapter {
@Autowired
private CustomInterceptor customInterceptor ;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(customInterceptor );
}
}