我在想,如果有一个任何注释Filter
类(Web应用程序)在春季启动? 也许@Filter
?
我想在我的项目中添加自定义过滤器。
春季启动参考指南提及FilterRegistrationBean
,但我不知道如何使用它。
我在想,如果有一个任何注释Filter
类(Web应用程序)在春季启动? 也许@Filter
?
我想在我的项目中添加自定义过滤器。
春季启动参考指南提及FilterRegistrationBean
,但我不知道如何使用它。
如果你想安装第三方过滤器,你可以使用FilterRegistrationBean
。 例如web.xml中的等效
<filter>
<filter-name>SomeFilter</filter-name>
<filter-class>com.somecompany.SomeFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SomeFilter</filter-name>
<url-pattern>/url/*</url-pattern>
<init-param>
<param-name>paramName</param-name>
<param-value>paramValue</param-value>
</init-param>
</filter-mapping>
这些会在你的两个bean @Configuration
文件
@Bean
public FilterRegistrationBean someFilterRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(someFilter());
registration.addUrlPatterns("/url/*");
registration.addInitParameter("paramName", "paramValue");
registration.setName("someFilter");
registration.setOrder(1);
return registration;
}
public Filter someFilter() {
return new SomeFilter();
}
上述用弹簧引导1.2.3测试
下面是包括在一个Spring引导MVC应用程序的自定义过滤器的一个方法的一个例子。 一定要包括在组件扫描包:
package com.dearheart.gtsc.filters;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;
@Component
public class XClacksOverhead implements Filter {
public static final String X_CLACKS_OVERHEAD = "X-Clacks-Overhead";
@Override
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader(X_CLACKS_OVERHEAD, "GNU Terry Pratchett");
chain.doFilter(req, res);
}
@Override
public void destroy() {}
@Override
public void init(FilterConfig arg0) throws ServletException {}
}
没有特别注明,以表示一个Servlet过滤器。 你刚才声明@Bean
类型的Filter
(或FilterRegistrationBean
)。 一个例子(添加自定义标题,所有响应)是在引导自己的EndpointWebMvcAutoConfiguration ;
如果你只是声明了一个Filter
将应用于所有请求。 如果您还添加了FilterRegistrationBean
你还可以指定单独的servlet和URL模式适用。
注意:
由于Spring引导1.4, FilterRegistrationBean
不会被弃用,并干脆搬到包从org.springframework.boot.context.embedded.FilterRegistrationBean
到org.springframework.boot.web.servlet.FilterRegistrationBean
有三种方式来增加您的过滤器,
@Component
@Bean
与Filter
的弹簧式@Configuration
@Bean
与FilterRegistrationBean
春季型@Configuration
如果你想让你的过滤器适用于无需定制的所有请求,使用#3否则无论是1号或2就行了。 当你把你的过滤器类中的相同或子包你并不需要指定#1组件扫描工作,只要SpringApplication
类。 对于#3,使用沿当你想春天来管理您的过滤器类,如把它自动有线依赖与#2才是必需的。 它工作得很好,对我来说,我的新过滤器,不需要任何依赖自动装配/注入。
虽然合并#2,#3作品很好,我很惊讶它不与两个过滤器应用两次结束。 我的猜测是,春天结合了这两种豆类之一,当调用相同的方法来创建他们两个。 如果你想要使用authowiring#3独自一人,你可以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;
}
UPDATE:二○一七年十二月一十六日:
有2点简单的方法,在春季启动1.5.8.RELEASE,不需要XML做到这一点。
第一种方式:如果你没有任何spacific URL模式,你可以使用@Component是这样的:(全码和细节在这里https://www.surasint.com/spring-boot-filter/ )
@Component
public class ExampleFilter implements Filter{
...
}
方式二:如果你想使用URL模式,你可以使用@WebFilter这样的:(全码和细节在这里https://www.surasint.com/spring-boot-filter-urlpattern/ )
@WebFilter(urlPatterns = "/api/count")
public class ExampleFilter implements Filter{
...
}
但是你也需要在你的@SpringBootApplication类添加注释@ServletComponentScan:
@ServletComponentScan
@SpringBootApplication
public class MyApplication extends SpringBootServletInitializer {
...
}
需要注意的是@Component是Spring的注解,但@WebFilter不是。 @WebFilter是Servlet的3注释。
这两种方法,你只需要在pom.xml的基本春天启动的依赖(不需要明确的Tomcat的嵌入式碧玉)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.8.RELEASE</version>
</parent>
<groupId>com.surasint.example</groupId>
<artifactId>spring-boot-04</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
警告:第一种方式,如果在春季启动控制器返回到一个JSP文件,请求将通过过滤器的两倍。
虽然在第二种方式中,请求将通过过滤器只有一次。
我倾向于第二种方式,因为它更类似于中的默认Servlet规范行为( https://docs.oracle.com/cd/E19879-01/819-3669/6n5sg7b0b/index.html )
你可以在这里看到更多的测试日志https://www.surasint.com/spring-boot-webfilter-instead-of-component/
这里是我的自定义过滤器类的例子:
package com.dawson.controller.filter;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.GenericFilterBean;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class DawsonApiFilter extends GenericFilterBean {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
if (req.getHeader("x-dawson-nonce") == null || req.getHeader("x-dawson-signature") == null) {
HttpServletResponse httpResponse = (HttpServletResponse) response;
httpResponse.setContentType("application/json");
httpResponse.sendError(HttpServletResponse.SC_BAD_REQUEST, "Required headers not specified in the request");
return;
}
chain.doFilter(request, response);
}
}
我把它添加到春季启动配置中添加它来配置类,如下所示:
package com.dawson.configuration;
import com.fasterxml.jackson.datatype.hibernate5.Hibernate5Module;
import com.dawson.controller.filter.DawsonApiFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
@SpringBootApplication
public class ApplicationConfiguration {
@Bean
public FilterRegistrationBean dawsonApiFilter() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new DawsonApiFilter());
// In case you want the filter to apply to specific URL patterns only
registration.addUrlPatterns("/dawson/*");
return registration;
}
}
从春天的文档,
嵌入式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引导+ Spring Security的,你可以做的是,在安全配置。
在下面的例子中,我加入UsernamePasswordAuthenticationFilter之前自定义过滤器(见所有默认的Spring Security过滤器和它们的顺序 )。
@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);
}
}
使用@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
}
}
您可以在实现了javax.servlet.Filter类使用@WebFilter javax.servlet.annotation.WebFilter
@WebFilter(urlPatterns = "/*")
public class MyFilter implements Filter {}
然后使用@ServletComponentScan注册
我看到了很多答案在这里,但我没有尝试任何人。 我刚刚创建的过滤器,如下面的代码。
import org.springframework.context.annotation.Configuration;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@WebFilter(urlPatterns = "/Admin")
@Configuration
public class AdminFilter implements Filter{
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("happened");
}
@Override
public void destroy() {
}
}
和阔叶剩余春季启动应用程序,因为它是。
它比答案的建议,但如果你是在你的web应用程序中使用Spring MVC中的好主意是使用Spring的HandlerInterceptor代替过滤器
它可以做同样的工作,但还 - 可与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并实现过滤网,使过滤器,它会做。
@Configuration
public class AppInConfig
{
@Bean
@Order(1)
public FilterRegistrationBean aiFilterRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new TrackingFilter());
registration.addUrlPatterns("/**");
registration.setOrder(1);
return registration;
}
@Bean(name = "TrackingFilter")
public Filter TrackingFilter() {
return new TrackingFilter();
}
}
首先,添加@ServletComponentScan
您SpringBootApplication类。
@ServletComponentScan
public class Application {
二,创建一个过滤器文件扩展过滤器或第三方筛选器类,并添加@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{
@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... ");
}
}
您需要实现过滤,需要用@WebFilter进行注释(URL模式=“/ *”)
而在应用程序或配置类,你需要添加@ServletComponentScan通过这一点,您的过滤器将获得注册。
我通过@Vasily科马罗夫看到答案。 类似的方法,但是使用抽象类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 );
}
}
大家都知道,春季启动是开发一个Web应用程序或StandaloneApp最小配置和自以为是设置的极好方法。
这是我如何在春季启动应用程序实现了网页过滤开发
我SpringBootApp规格: -
春天开机版本:2.0.4.RELEASE
Java版本:8.0
Servlet规范:Servlet的3.0(强制性和重要)
我宣布以下列方式我的网页过滤,秉承Servlet的规格3.0
这是定义为一个更换到web.xml基于定义一个过滤器的编程方法。
“@WebFilter”注释将由容器部署期间被处理,其中,它被发现将被创建为每个配置和施加到URL模式,javax.servlet.Servlets和javax.servlet.DispatcherTypes过滤器类。
为了完全避免web.xml和实现“部署” Web应用程序: -
要部署春季启动应用程序“传统战争”,应用程序类应该扩展SpringBootServletInitializer。
注:: SpringBootServletInitializer是一个“编程实现” web.xml中的参考的Servlet 3.0+规范,这需要WebApplicationInitializer的实现。
因此,SpringBootApplication不需要“web.xml中”作为其应用程序类扫描为(延伸SpringBootServletInitializer之后)
- @WebFilter,
- @WebListener和
- @WebServlet。
注释@ServletComponentScan
这个注解使扫描的基本软件包与@WebFilter,@WebListener和@WebServlet注释的Web组件。
由于嵌入式容器不支持@WebServlet,@WebFilter和@WebListener注释,春天开机,嵌入式的容器大大依托,推出了这款新的注释@ServletComponentScan支持使用这些3个标注一些相关的罐子。
使用嵌入式Servlet容器时,才执行扫描。
以下是我的春节,引导应用类定义: -
自定义Servlet的初始化程序: -
在这里:我已经定义了一个自定义类:“ServletInitializer”延伸类:SpringBootServletInitializer。
如前所述,SpringBootServletInitializer负责扫描注释: -
- @WebFilter,
- @WebListener和
- @WebServlet。
因此春节引导应用程序类应该
过滤器在记录文件大多是用它根据您在该项目还是让我对log4j2解释使用记录变化:
<Filters>
<!-- It prevents error -->
<ThresholdFilter level="error" onMatch="DENY" onMismatch="NEUTRAL"/>
<!-- It prevents debug -->
<ThresholdFilter level="debug" onMatch="DENY" onMismatch="NEUTRAL" />
<!-- It allows all levels except debug/trace -->
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY" />
</Filters>
过滤器用于限制数据,我使用的阈滤波器进一步限制在我提到可以那边被限制水平的流动数据的电平。 为了您进一步refrence看到log4j2水平顺序 - Log4J的级别:ALL> TRACE> DEBUG> INFO> WARN> ERROR> FATAL> OFF