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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33331042/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 00:50:39  来源:igfitidea点击:

How to handle HTTP OPTIONS requests in Spring Boot?

springspring-mvcspring-boothttp-options-method

提问by Jonik

First off, I've read "How to handle HTTP OPTIONS with Spring MVC?" but the answers do not seem directly applicable to Spring Boot.

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

It looks like I should do this:

看起来我应该这样做:

configure the dispatcherServlet by setting its dispatchOptionsRequestto true

通过将其设置为dispatchOptionsRequest来配置 dispatcherServlet true

But how to do that, given that I have no XML configs, or any variety of DispatcherServletinitializer class in my code (mentioned by this answer)?

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

In a @RestControllerclass, I have a method like this, which currently does not get invoked.

在一个@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; a simple setup not very different from that in Spring REST guide.

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

回答by Bohuslav Burghardt

Option 1: Spring Boot properties (Spring Boot 1.3.0+ only)

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

Starting with Spring Boot 1.3.0 this behavior can be configured using following property:

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

spring.mvc.dispatch-options-request=true

Option 2: Custom DispatcherServlet

选项 2:自定义 DispatcherServlet

DispatcherServletin Spring Boot is defined by DispatcherServletAutoConfiguration. You can create your own DispatcherServletbean somewhere in your configuration classes, which will be used instead of the one in auto configuration:

DispatcherServlet在 Spring Boot 中由DispatcherServletAutoConfiguration. 您可以DispatcherServlet在配置类中的某处创建自己的bean,它将用于代替自动配置中的bean:

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

But be aware that defining your DispatcherServletbean will disable the auto configuration, so you should manually define other beans declared in the autoconfiguration class, namely the ServletRegistrationBeanfor DispatcherServlet.

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

Option 3: BeanPostProcessor

选项 3: BeanPostProcessor

You can create BeanPostProcessorimplementation which will set the dispatchOptionsRequestattribute to truebefore the bean is initialized. Yoy can put this somewhere in your configuration classes:

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

@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;
    }
}

Option 4: SpringBootServletInitializer

选项 4: SpringBootServletInitializer

If you had SpringBootServletInitializerin your application you could do something like this to enable OPTIONS dispatch:

如果你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");
    }
}

That would however only work if you deployed your app as a WAR into Servlet container, as the SpringBootServletInitializercode is not executed when running your Spring Boot app using mainmethod.

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

回答by beaudet

I was running into this issue with a Spring Boot 1.3.x based rest app and while diagnosing the problem I allowed my Spring Tool Suite to update to the latest version.

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

When I created a new test Spring Boot RestController in the updated STS, it worked as the documentation advertises under Spring 4.3. I noticed that the Maven dependency had jumped to spring boot 1.5.8 in the new test app, so I just changed the dependency for the old app to update it to spring boot 1.5.8 / spring 4.3.12. That fixed the issue and now it's working as advertised with a RequestMapping annotation specifying an interest in handling the OPTIONS requests...

当我在更新的 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})

... now sends the OPTIONS request to the handler.

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

So, if you are able to update to a later version of Spring, you should have no need to define any special configurations in order enable OPTIONS request method handling (Spring 4.3.12 / Spring Boot 1.5.8).

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

回答by ron190

You can easily add custom method OPTIONSto StrictHttpFirewallwith Spring Boot 2.2.6 :

您可以轻松地添加自定义的方法OPTIONSStrictHttpFirewall与Spring 2.2.6引导:

@Bean
public StrictHttpFirewall httpFirewall() {

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

    return firewall;
}