34

首先,我读过“如何使用 Spring MVC 处理 HTTP 选项? ”但答案似乎并不直接适用于 Spring Boot。

看起来我应该这样做:

通过将 dispatcherServlet 设置 dispatchOptionsRequesttrue

但是,鉴于我的DispatcherServlet代码中没有 XML 配置或任何类型的初始化程序类(此答案提到),如何做到这一点?

在一个@RestController类中,我有一个这样的方法,目前没有被调用。

@RequestMapping(value = "/foo", method = RequestMethod.OPTIONS)
public ResponseEntity options(HttpServletResponse response) {
    log.info("OPTIONS /foo called");
    response.setHeader("Allow", "HEAD,GET,PUT,OPTIONS");
    return new ResponseEntity(HttpStatus.OK);
}

Spring Boot 1.2.7.RELEASE;一个简单的设置,与Spring REST 指南中的设置没有太大区别 。

4

3 回答 3

31

选项 1:Spring Boot 属性(仅限 Spring Boot 1.3.0+)

从 Spring Boot 1.3.0 开始,可以使用以下属性配置此行为:

spring.mvc.dispatch-options-request=true

选项 2:自定义DispatcherServlet

DispatcherServlet在 Spring Boot 中由DispatcherServletAutoConfiguration. 您可以在配置类中的某个位置创建自己的DispatcherServletbean,而不是在自动配置中使用它:

@Bean(name = DispatcherServletAutoConfiguration.DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)
public DispatcherServlet dispatcherServlet() {
    DispatcherServlet dispatcherServlet = new DispatcherServlet();
    dispatcherServlet.setDispatchOptionsRequest(true);
    return dispatcherServlet;
}

但请注意,定义您的DispatcherServletbean 将禁用自动配置,因此您应该手动定义在自动配置类中声明的其他 bean,即ServletRegistrationBeanfor DispatcherServlet

选项 3:BeanPostProcessor

您可以创建BeanPostProcessor实现,该实现将在 bean 初始化之前将dispatchOptionsRequest属性设置为。trueYoy 可以把它放在你的配置类中的某个地方:

@Bean
public DispatcherServletBeanPostProcessor dispatcherServletBeanPostProcessor() {
    return new DispatcherServletBeanPostProcessor();
}

public static class DispatcherServletBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof DispatcherServlet) {
            ((DispatcherServlet) bean).setDispatchOptionsRequest(true);
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
}

选项 4:SpringBootServletInitializer

如果你SpringBootServletInitializer在你的应用程序中有你可以做这样的事情来启用 OPTIONS 调度:

public class ServletInitializer extends SpringBootServletInitializer {
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(Application.class);
    }

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        super.onStartup(servletContext);
        servletContext.getServletRegistration(DispatcherServletAutoConfiguration.DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)
                .setInitParameter("dispatchOptionsRequest", "true");
    }
}

但是,只有当您将应用程序作为 WAR 部署到 Servlet 容器中时,这才有效,因为在使用方法SpringBootServletInitializer运行 Spring Boot 应用程序时不会执行代码。main

于 2015-10-25T16:17:35.513 回答
0

OPTIONS您可以StrictHttpFirewall使用 Spring Boot 2.2.6轻松添加自定义方法:

@Bean
public StrictHttpFirewall httpFirewall() {

    StrictHttpFirewall firewall = new StrictHttpFirewall();
    firewall.setAllowedHttpMethods(Arrays.asList("GET", "POST", "OPTIONS", "FOO"));

    return firewall;
}
于 2020-04-25T20:54:08.303 回答
0

我在使用基于 Spring Boot 1.3.x 的 rest 应用程序时遇到了这个问题,在诊断问题时,我允许我的 Spring Tool Suite 更新到最新版本。

当我在更新的 STS 中创建一个新的测试 Spring Boot RestController 时,它的工作原理与 Spring 4.3 下的文档广告一样。我注意到新测试应用程序中的 Maven 依赖项已经跳转到 spring boot 1.5.8,所以我只是将旧应用程序的依赖项更改为 spring boot 1.5.8 / spring 4.3.12。这解决了这个问题,现在它正在使用 RequestMapping 注释,指定对处理 OPTIONS 请求的兴趣...

@RequestMapping(value="/account/{id}", method={RequestMethod.OPTIONS,RequestMethod.GET})

...现在将 OPTIONS 请求发送到处理程序。

因此,如果您能够更新到更高版本的 Spring,则无需定义任何特殊配置即可启用 OPTIONS 请求方法处理(Spring 4.3.12 / Spring Boot 1.5.8)。

于 2017-11-13T20:52:05.187 回答