这是一个使用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的自动配置。

09-05 10:59