【问题标题】:How to handle HTTP OPTIONS with Spring MVC?如何使用 Spring MVC 处理 HTTP OPTIONS?
【发布时间】:2012-03-20 06:30:27
【问题描述】:

我想通过我的控制器使用 Spring MVC 拦截 OPTIONS 请求,但它被 DispatcherServlet 捕获。我该如何处理?

【问题讨论】:

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


【解决方案1】:

我为初学者的 Bozho 答案添加了更多细节。 有时让 Spring Controller 管理 OPTIONS 请求很有用(例如,设置正确的“Access-Control-Allow-*”标头以服务 AJAX 调用)。 但是,如果您尝试常见的做法

@Controller
public class MyController {

    @RequestMapping(method = RequestMethod.OPTIONS, value="/**")
    public void manageOptions(HttpServletResponse response)
    {
        //do things
    }
}

因为 DispatcherServlet 会拦截客户端的 OPTIONS 请求,所以它不起作用。

解决方法很简单:

您必须...从您的 web.xml 文件中配置 DispatcherServlet,如下所示:

...
  <servlet>
    <servlet-name>yourServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>dispatchOptionsRequest</param-name>
      <param-value>true</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
...

添加“dispatchOptionsRequest”参数并将其设置为true。

现在 DispatcherServlet 会将 OPTIONS 处理委托给您的控制器,然后执行 manageOption() 方法。

希望这会有所帮助。

PS。老实说,我看到 DispatcherServlet 将允许的方法列表附加到响应中。就我而言,这并不重要,我放手了。可能需要进一步检查。

【讨论】:

  • 但这不起作用,例如,如果在端点“/x/y”处注册了处理程序方法。现在对 /x 的 OPTIONS 请求有效,但对 /x/y 无效,是否有任何选项可以解决此问题?意味着将此选项处理添加到所有已注册的端点?我想到了拦截器,但还有其他方法吗?
【解决方案2】:
@RequestMapping(value="/youroptions", method=RequestMethod.OPTIONS)
public View getOptions() {

}

您应该通过将 dispatcherServlet 的 dispatchOptionsRequest 设置为 true 来配置 dispatcherServlet

【讨论】:

  • 实际上它不起作用,因为 DispatcherServlet 会拦截请求并处理它。应该改为配置 DispatcherServlet。我对这个问题感到很痛苦,目前我部分解决了这个问题。我想为社区发布我的解决方案,但是......由于我的声誉少于 100,stackoverflow 迫使我等待 8 小时才能让我回答自己的问题。
  • 是的,这就是解决方案。我应该以前见过你的,天哪! XD 然而,这是一个“部分”解决方案,因为 DispatcherServlet 在委派您的控制器之前会做“一些工作”。事实上,即使您不会触摸“允许”标题,它也会填充“允许的方法”列表。就我而言,这不是问题,但我想它是给别人的。
  • 重要更新:从 Spring Framework 4.3 开始,OPTIONS 请求将默认受支持,请参阅jira.spring.io/browse/SPR-13130 了解更多详细信息。
【解决方案3】:

作为对上述 2 个答案的快速补充,以下是如何在 servlet 3(无 web.xml)环境中启用 dispatchOptionsRequest,因为我花了一段时间才弄清楚如何在非 xml 设置中应用上述答案.

在 spring 3.2 / servlet 3 环境中,您将拥有各种DispatcherServlet 初始化器类,它是 web.xml 的 java 等价物;就我而言,它是AbstractAnnotationConfigDispatcherServletInitializer。添加以下代码将启用dispatchOptionsRequest:

    @Override
    protected void customizeRegistration(Dynamic registration) {
        registration.setInitParameter("dispatchOptionsRequest", "true");
    }

【讨论】:

    【解决方案4】:

    我采取了以下方法:

    使用 Maven (or manually) 拉入这种依赖关系:

    <dependency>
        <groupId>com.thetransactioncompany</groupId>
        <artifactId>cors-filter</artifactId>
        <version>1.3.2</version>
    </dependency>
    

    这有一个实现来捕获所有入站 OPTIONS 请求。在 web.xml 文件中添加以下配置:

    <filter>
       <filter-name>CORS</filter-name>
       <filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>       
       <init-param>
          <param-name>cors.supportedHeaders</param-name>
          <param-value>Content-Type,Accept,Origin</param-value>
       </init-param>
    </filter>
    
    <filter-mapping>
       <filter-name>CORS</filter-name>
       <url-pattern>/*</url-pattern>
    </filter-mapping>
    

    我在 /** 方法中看到的问题是更具体的控制器实现将覆盖它。

    【讨论】:

      【解决方案5】:

      对于没有 web.xml 文件的 Spring,基于 Paul Adamson 的回答,我只是将参数 dispatchOptionsRequest 设置为 true 到调度程序中,以处理 Options 方法调用。

      ServletRegistration.Dynamic dispatcher = container.addServlet("dispatcher", new        DispatcherServlet(applicationContext));
      
      dispatcher.setInitParameter("dispatchOptionsRequest", "true");                
      
      dispatcher.setLoadOnStartup(1);
      dispatcher.addMapping("/*");
      

      【讨论】:

        猜你喜欢
        • 2016-01-24
        • 2012-04-19
        • 2015-08-12
        • 2012-12-02
        • 2013-02-15
        • 2011-10-23
        • 1970-01-01
        • 2016-06-05
        相关资源
        最近更新 更多