这是一个使用Maven的Spring Boot Java项目。
如果我从WebConfig中删除@Configuration批注,则将构建应用程序,但该类似乎被忽略。如果包含它,则该应用程序将失败,并显示以下消息:
启动Tomcat上下文时出错。例外:
java.lang.ClassCastException。信息:
org.springframework.boot.web.servlet.DispatcherType无法强制转换为
javax.servlet.DispatcherType。应用程序运行失败。
如何正确设置Spring Boot以使用过滤器?
这是主要的应用类别:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
@SpringBootApplication
public class GetJobDetailsApplication extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(GetJobDetailsApplication.class);
}
public static void main(String[] args) {
SpringApplication.run(GetJobDetailsApplication.class, args);
}
}
这是控制器:
import java.util.Map;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MainRESTController {
// inject via application.properties
@Value("${welcome.message:test}")
private String message = "Hello World";
@RequestMapping("/")
public String welcome(Map<String, Object> model) {
model.put("message", this.message);
return "welcome";
}
}
这是我设置过滤器的WebConfig:
import org.owasp.filters.ClickjackFilter;
import org.springframework.boot.web.servlet.DispatcherType;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.ShallowEtagHeaderFilter;
import java.util.EnumSet;
@Configuration
public class WebConfig {
@Bean
public FilterRegistrationBean clickjackFilterRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(clickjackFilter());
registration.addUrlPatterns("/");
registration.addInitParameter("paramName", "paramValue");
registration.setName("clickjackFilter");
registration.setOrder(1);
return registration;
}
@Bean(name = "clickjackFilter")
public ClickjackFilter clickjackFilter() {
return new ClickjackFilter();
}
@Bean
public FilterRegistrationBean shallowEtagHeaderFilter() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new ShallowEtagHeaderFilter());
registration.setDispatcherTypes(EnumSet.allOf(DispatcherType.class));
registration.addUrlPatterns("/");
return registration;
}
}
这是clickjackFilter类:
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;
public class ClickjackFilter implements Filter {
private String mode = "DENY";
/**
* Add X-FRAME-OPTIONS response header to tell IE8 (and any other browsers who
* decide to implement) not to display this content in a frame. For details, please
* refer to http://blogs.msdn.com/sdl/archive/2009/02/05/clickjacking-defense-in-ie8.aspx.
*/
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletResponse res = (HttpServletResponse) response;
res.addHeader("X-FRAME-OPTIONS", mode);
chain.doFilter(request, response);
}
public void destroy() {
}
public void init(FilterConfig filterConfig) {
String configMode = filterConfig.getInitParameter("mode");
if (configMode != null) {
mode = configMode;
}
}
}
pom.xml文件中的依赖项:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-jaxrs</artifactId>
<version>1.5.9</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-core</artifactId>
<version>${apachetiles.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-jsp</artifactId>
<version>${apachetiles.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-extras</artifactId>
<version>${apachetiles.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-api</artifactId>
<version>${apachetiles.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-servlet</artifactId>
<version>${apachetiles.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<version>2.1.4.RELEASE</version>
</dependency>
<!-- Tomcat embedded container-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<!-- JSTL for JSP -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<!-- Need this to compile JSP -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
<!-- Need this to compile JSP,
tomcat-embed-jasper version is not working -->
<dependency>
<groupId>org.eclipse.jdt.core.compiler</groupId>
<artifactId>ecj</artifactId>
<version>4.6.1</version>
<scope>provided</scope>
</dependency>
<!-- Optional, test for static content, bootstrap CSS-->
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>3.3.7</version>
</dependency>
</dependencies>
最佳答案
仔细查看您的堆栈跟踪,可以尝试将DispatcherType设置为
java.lang.Object
java.lang.Enum<DispatcherType>
javax.servlet.DispatcherType
因为
FilterRegistrationBean
期望集合javax.servlet.DispatcherType
的参数类型为setDispatcherTypes()
或者,您可以使用以下注释直接注册过滤器bean:
@Order(Ordered.LOWEST_PRECEDENCE -1)
@Component
public class ABCFilter implements Filter {
------
}
通常在春季启动中,您将过滤器配置为:
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
@Autowired
HandlerInterceptor customInjectedInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(...)
...
registry.addInterceptor(customInjectedInterceptor).addPathPatterns("/**");
}
}
或者,如果您使用的是Spring 5x,则:
@Configuration
public WebConfig implements WebMvcConfigurer {
// ...
}
通过这样做,我们实际上是在自定义spring boot自动配置bean,以便springboot仍然可以自动配置所有其他东西。如果您使用springboot,请考虑删除@EnableWebMvc并使用springboot的自动配置。