如何在Spring Boot中处理HTTP OPTIONS请求?

时间:2015-10-25 14:52:42

标签: spring spring-mvc spring-boot http-options-method

首先,我已阅读" How to handle HTTP OPTIONS with Spring MVC?"但答案似乎并不直接适用于Spring Boot。

看起来我应该这样做:

  

通过设置dispatcherServlet来配置它   dispatchOptionsRequesttrue

但是如何做到,因为我的代码中没有XML配置或任何DispatcherServlet初始化类(mentioned by this answer)?

@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 guide中的设置没有太大差别。

3 个答案:

答案 0 :(得分:24)

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

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

spring.mvc.dispatch-options-request=true

选项2:自定义DispatcherServlet

Spring Boot中的

DispatcherServletDispatcherServletAutoConfiguration定义。您可以在配置类中的某处创建自己的DispatcherServlet bean,而不是自动配置中的bean:

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

但请注意,定义DispatcherServlet bean将禁用自动配置,因此您应手动定义autoconfiguration类中声明的其他bean,即ServletRegistrationBean的{​​{1}}。

选项3:DispatcherServlet

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

true

选项4:@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; } }

如果您的应用程序中有SpringBootServletInitializer,您可以执行以下操作以启用OPTIONS调度:

SpringBootServletInitializer

但是,只有在将应用程序作为WAR部署到Servlet容器中时才会起作用,因为在使用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"); } } 方法运行Spring Boot应用程序时未执行SpringBootServletInitializer代码。

答案 1 :(得分:0)

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

当我在更新的STS中创建一个新的测试Spring Boot RestController时,它在Spring 4.3下作为文档广告工作。我注意到Maven依赖在新的测试应用程序中跳到了春季启动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)定义任何特殊配置。

答案 2 :(得分:0)

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

@Bean
public StrictHttpFirewall httpFirewall() {

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

    return firewall;
}