简体   繁体   English

如何在Spring MVC 2.5应用程序中更改HTTP OPTIONS请求的响应?

[英]How do I change the response for a HTTP OPTIONS request in a Spring MVC 2.5 application?

This sounds like a trivial question but somehow I can't seem to figure it out. 这听起来像一个微不足道的问题但不知何故我似乎无法弄明白。

I have a Spring MVC application. 我有一个Spring MVC应用程序。 I don't support any http methods except GET and POST. 我不支持除GET和POST之外的任何http方法。 I have the following set in all my controllers beans: 我在所有控制器bean中都有以下设置:

<property name="supportedMethods" value="GET,POST"/>

However, an OPTIONS request sent to my application sends back a response that shows all http methods as allowed. 但是,发送到我的应用程序的OPTIONS请求会发回一个响应,该响应将所有 http方法显示为允许。

How do I change the OPTIONS response to show only GET and POST methods as allowed? 如何更改OPTIONS响应以仅显示允许的GET和POST方法? I know I could do this in a servlet by overriding the doOptions method, but I am not sure about a Spring MVC application. 我知道我可以通过覆盖doOptions方法在servlet中执行此操作,但我不确定Spring MVC应用程序。 Do I have to extend the DispatcherServlet and override doOptions ? 我是否必须扩展DispatcherServlet并覆盖doOptions

The application is using Spring mvc 2.5.6 with SimpleFormController based controllers and xml based config. 该应用程序使用Spring mvc 2.5.6和基于SimpleFormController的控制器和基于xml的配置。

Caveat: I have not handled OPTIONS messages. 警告:我还没有处理OPTIONS消息。

In your request handler (annotated with @Controller) you can use RequestMethod.OPTIONS to handle an Options request. 在您的请求处理程序(使用@Controller注释)中,您可以使用RequestMethod.OPTIONS来处理Options请求。 For example you might use 例如,您可以使用

  ... stuff ...  
  @RequestMapping(RequestMethod.OPTIONS)  
  public String processOptions()
  {
  ... stuff ...
  }

I think you could invoke WebContentGenerator#setSupportedMethods which receives as input parameter an array of strings containing supported methods. 我想你可以调用WebContentGenerator#setSupportedMethods ,它接收包含支持方法的字符串数组作为输入参数。 WebContentGenerator is the base class for spring 2.x controllers, so you just need to invoke this method during the construction of your controller that surely extends it. WebContentGenerator是spring 2.x控制器的基类,因此您只需要在构造控制器期间调用此方法,这肯定会扩展它。 You also could use the Constructor of WebContentGenerator that receives a string varargs (supported methods) as input parameter. 您还可以使用WebContentGenerator的构造函数来接收字符串varargs(支持的方法)作为输入参数。

Unfortunately, the doOptions method in FrameworkServlet class invokes super.doOptions(request, response); 不幸的是, FrameworkServlet类中的doOptions方法调用了super.doOptions(request, response); of HttpServlet class. HttpServlet类。 The ouput of this method is based on the declared methods in the servlet, something like this: 此方法的输出基于servlet中声明的方法,如下所示:

Method[] methods = getAllDeclaredMethods(this.getClass());

for (int i = 0; i < methods.length; i++) {
    Method m = methods[i];

    if (m.getName().equals("doGet")) {
        ALLOW_GET = true;
        ALLOW_HEAD = true;
    }
    if (m.getName().equals("doPost"))
        ALLOW_POST = true;
    if (m.getName().equals("doPut"))
        ALLOW_PUT = true;
    if (m.getName().equals("doDelete"))
        ALLOW_DELETE = true;
}

The DispatcherServlet class (and its base class FrameworkServlet) declares all these methods: doPut , doDelete , doGet , doPost etc., so the output of doOptions is not what you desire. DispatcherServlet类(及其基类FrameworkServlet)声明了所有这些方法: doPutdoDeletedoGetdoPost等,因此doOptions的输出不是您想要的。 I think the only way is subclassing the DispatcherServlet. 我认为唯一的方法是继承DispatcherServlet。

I know that this is a bit old but I've found additional info on this question that I hope will help others in the future. 我知道这有点旧了,但我已经找到了关于这个问题的更多信息,我希望将来可以帮助其他人。

The @RequestMapping(RequestMethod.OPTIONS) approach won't work immediately using the DispatcherServlet out of the box since its superclass, FrameworkServlet, first delegates to its superclass, HttpServlet, as noted above which scans the servlet to see if it implements the doXXX methods and sets the Allow header accordingly. @RequestMapping(RequestMethod.OPTIONS)方法无法立即使用DispatcherServlet开箱即用,因为它的超类FrameworkServlet首先委托给它的超类HttpServlet,如上所述,它扫描servlet以查看它是否实现了doXXX方法并相应地设置Allow标头。 But following the call to super.doOptions(...) it then has these lines: 但是在调用super.doOptions(...)后,它会有以下几行:

if (this.dispatchOptionsRequest) {
     processRequest(request, response);
}

And there is a setDispatchOptionsRequest(boolean) that can be used to set the dispatchOptionsRequest value to true. 并且有一个setDispatchOptionsRequest(boolean)可用于将dispatchOptionsRequest值设置为true。 Only then will the DispatcherServlet pass to the controller the OPTIONS request to an appropriately annotated method. 只有这样,DispatcherServlet才会向适当的注释方法传递OPTIONS请求给控制器。

I needed to do this to allow the OPTIONS request to return different values based upon authorizations of the current user. 我需要这样做以允许OPTIONS请求根据当前用户的授权返回不同的值。 So by subclassing DispatcherServlet and setting that parameter in its default constructor I was finally able to receive the call in my controller for http OPTIONS requests and handle it on my own. 因此,通过继承DispatcherServlet并在其默认构造函数中设置该参数,我终于能够在我的控制器中接收对http OPTIONS请求的调用并自行处理它。

And one more thought, in that controller method you can declare a parameter of type HttpServletResponse and Spring will hand the instance to you. 还有一个想法,在那个控制器方法中,你可以声明一个HttpServletResponse类型的参数,Spring将把实例交给你。 Once had you can call reset() to purge the Allow header already set and roll your own as needed. 一旦你有可以调用reset()来清除已经设置的Allow头,并根据需要滚动你自己的头。

(Note: A similar patter is had in FrameworkServlet for http TRACE support via a setDispatchTraceRequest if you plan on getting those requests through to your controller methods annotated with @RequestMapping(RequestMethod.TRACE)). (注意:如果您计划将这些请求发送到使用@RequestMapping(RequestMethod.TRACE)注释的控制器方法,则FrameworkServlet中的类似模式用于通过setDispatchTraceRequest支持http TRACE。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在HTTP响应中进行单元测试“缓存控制”-Spring MVC Application - How to unit test “cache control” in http response - spring mvc application 如何通过Spring RestTemplate更改获取请求中的响应http标头? - How to change response http header in get request by spring RestTemplate? 通过Spring MVC Controller动作,如何获得对请求/响应的访问? - From a spring mvc controller action, how do I get access to request/response? 如何将请求发送到另一个域并在Spring MVC控制器中获取响应正文? - How do I send a request to another domain and get the response body in a Spring MVC controller? Spring和HTTP选项请求 - Spring and HTTP Options request 如何使用Spring MVC处理HTTP OPTIONS? - How to handle HTTP OPTIONS with Spring MVC? 如何在 Spring MVC 2.5 项目中使用 MockMvc? - How can I use MockMvc in Spring MVC 2.5 project? 我想要接受 https 请求并将此请求发送到 http 上的其他应用程序并将此 http 响应发送回 https req 的 Spring Boot 应用程序 - I want spring boot application which accepts https request and send this request to other app on http and send this http response back to https req Spring Security:如何更改响应的 HTTP 状态? - Spring Security: how to change HTTP Status for response? 使用Apache tomcat和Spring框架的HTTP请求和响应流程 - Flow of HTTP request and response with Apache tomcat and spring framework for an application
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM