Can Spring auto-generate the 'Allow' header for the OPTIONS method?

When I configure my RequestMapping in Spring MVC, I would like to automatically generate the correct Allow header when the OPTIONS method is used.

For example, using this controller:

 @Controller @RequestMapping("/test") public class TestController { @RequestMapping(method = RequestMethod.GET) ResponseEntity<String> getTest() { return new ResponseEntity<>("test", HttpStatus.OK); } } 

Right now, if I make an OPTIONS request to this URL, I get 405, the method is not allowed. Instead, I would like it to respond automatically with

Allow: GET, OPTIONS and 204 - No content

I have an idea to add an interceptor like this:

 @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new HandlerInterceptor() { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if("OPTIONS".equalsIgnoreCase(request.getMethod())){ response.setHeader("Allow", "GET, OPTIONS"); response.setStatus(204); //TODO figure out the @Controller and what possible methods exist return false; } return true; } //Deleted excess methods for brevity }); } 

Is this functionality without what I am writing a custom interceptor? If not, how can I solve TODO and find which annotations exist on the same URL that the OPTIONS call has occurred?

+6
source share
3 answers

Extend the answers of Sotiros and Jhadesdew. If you use Java Config (for example, in Spring Boot), you can configure DispatchServlet to enable the OPTIONS request by configuring @Bean as follows:

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

Then I created a static helper that adopts the HttpMethods tactic as follows:

 public static ResponseEntity<Void> allows(HttpMethod... methods) { HttpHeaders headers = new HttpHeaders(); Set<HttpMethod> allow = new HashSet<>(); for(HttpMethod method: methods){ allow.add(method); } headers.setAllow(allow); return new ResponseEntity<>(headers, HttpStatus.NO_CONTENT); } 

This makes it easy to create your own OPTIONS displays:

 @RequestMapping(method = RequestMethod.OPTIONS) ResponseEntity<Void> getProposalsOptions() { return allows(HttpMethod.GET, HttpMethod.OPTIONS); } 

Although I think it makes sense that Spring MVC can automatically respond to OPTIONS , you cannot do this through Interceptor , but perhaps through a custom DispatcherServlet .

The advantage of writing your own OPTIONS answer is that it makes sense to configure OPTIONS in some cases based on user roles. For example, an unauthenticated API user can get Allow GET, OPTIONS , but the administrator will get the full API Allow GET, PUT, DELETE, OPTIONS . You set up the answer based on exploring user roles when calling OPTIONS .

+5
source

I do not know how to make it general, it currently works, although it is not general.

set dispatchOptionsRequest to true for the dispatcher servlet in your web.xml, otherwise this will prevent the servlet container from routing OPTIONS to the application:

 <servlet> <servlet-name>mvc-dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring/mvc-dispatcher-servlet.xml</param-value> </init-param> <init-param> <param-name>dispatchOptionsRequest</param-name> <param-value>true</param-value> </init-param> </servlet> 

Then adding this to the controller will return Allow: GET, OPTIONS and 204 - No content:

 @RequestMapping(value = "/tryoptions", method = RequestMethod.OPTIONS) @ResponseStatus(value = HttpStatus.NO_CONTENT) public ResponseEntity tryOptions(HttpSession session) throws Exception { HttpHeaders headers = new HttpHeaders(); headers.set("Allow","OPTIONS, GET"); return new ResponseEntity(headers, HttpStatus.NO_CONTENT); } 
+2
source

Changes made in Spring 4.3 have simplified this use case. From now on, the OPTIONS answer is automatically prepared for all mappings in your application. There is no need to manually configure the framework, since the function is available out of the box.

By default, the HTTP OPTIONS request is processed by setting the "Allow" parameter, the response to HTTP methods explicitly declared on all @RequestMapping methods with the corresponding URL patterns. When no HTTP methods are explicitly declared, the "Allow" header is set to "GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS"

+2
source

All Articles