Spring Boot中是否有Filter类(用于web应用程序)的注释?也许@Filter ?
我想在我的项目中添加一个自定义过滤器。
Spring Boot参考指南中提到过 FilterRegistrationBean,但我不确定如何使用它。
Spring Boot中是否有Filter类(用于web应用程序)的注释?也许@Filter ?
我想在我的项目中添加一个自定义过滤器。
Spring Boot参考指南中提到过 FilterRegistrationBean,但我不确定如何使用它。
当前回答
众所周知,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 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;
}
}
这是一个建议而不是答案,但如果你在你的web应用程序中使用Spring MVC,最好使用Spring HandlerInterceptor而不是Filter。
它可以做同样的工作,但是
可以使用ModelAndView吗 它的方法可以在请求处理之前和之后调用,或者在请求完成之后调用。 它很容易测试
1. 实现HandlerInterceptor接口,并向类中添加@Component注释
@Component
public class SecurityInterceptor implements HandlerInterceptor {
private static Logger log = LoggerFactory.getLogger(SecurityInterceptor.class);
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
request.getSession(true);
if(isLoggedIn(request))
return true;
response.getWriter().write("{\"loggedIn\":false}");
return false;
}
private boolean isLoggedIn(HttpServletRequest request) {
try {
UserSession userSession = (UserSession) request.getSession(true).getAttribute("userSession");
return userSession != null && userSession.isLoggedIn();
} catch(IllegalStateException ex) {
return false;
}
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
}
}
2. 配置拦截器
@Configuration
public class WebConfig implements WebMvcConfigurer {
private HandlerInterceptor securityInterceptor;
@Autowired
public void setSecurityInterceptor(HandlerInterceptor securityInterceptor) {
this.securityInterceptor = securityInterceptor;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(securityInterceptor).addPathPatterns("/**").excludePathPatterns("/login", "/logout");
}
}
使用@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
你可以在实现javax.servlet.Filter的类上使用@WebFilter javax.servlet.annotation.WebFilter:
@WebFilter(urlPatterns = "/*")
public class MyFilter implements Filter {
}
然后使用@ServletComponentScan注册。