3

I'm using Spring Data REST to build a RESTful API. Until now my HTML GUI for this RESTful service was served from the same Tomcat and I had no problems wit Cross Origin requests.

Now I want to serve the static files from a different server. This means the API is on another domain/port. Browsers will send the OPTIONS request to get the Access-Control headers from the server. Unfortunately Spring Data REST does not handle those OPTIONS requests and even returns a HTTP 500.

I tried creating a custom controller that handles all OPTIONS requests

@Controller
@RequestMapping(value = "/**", method = RequestMethod.OPTIONS)
public class OptionsController {

    @RequestMapping
    public ResponseEntity options() {
        return new ResponseEntity<Void>(HttpStatus.OK);
    }
}

Which worked for OPTIONS, but then all other requests (like GET) ceased to work.

OPTIONS requests are switched on via the dispatchOptionsRequest dispatcher servlet parameter.

CodesInChaos
  • 106,488
  • 23
  • 218
  • 262
FrontierPsychiatrist
  • 1,343
  • 10
  • 20

2 Answers2

0

tl;dr: currently Spring Data REST does not answer OPTIONS requests at all.

It might be worth opening a ticket in our JIRA.

Browsers will send the OPTIONS request to get the Access-Control headers from the server.

Is that specified somewhere? If so, it would be cool if the ticket description included a link to that spec.

A few comments regarding your approach for a workaround:

  1. @RequestMapping on the controller method overrides the method attribute and expectedly now matches all HTTP methods, which is why you see all requests intercepted. So you need to define OPTIONS as HTTP method there, too (or maybe instead of in the class mapping).
  2. You're not returning any Allow header which is the whole purpose of OPTIONS in the first place.
  3. I wonder if the approach in general makes sense as it'll be hard to reason about the supported HTTP methods in general.
Oliver Drotbohm
  • 80,157
  • 18
  • 225
  • 211
  • Thanks for the answer! I tried 1), should have posted that. Did not work. As soon as I register my controller no Data REST exported method does work. The headers are added in a filter. Point 3, well I think CORS is a common problem and should be supported, especially for REST APIs. – FrontierPsychiatrist Jun 25 '14 at 14:10
  • 2
    I opened https://jira.spring.io/browse/DATAREST-333. References to the w3c and mozilla are included. – FrontierPsychiatrist Jun 25 '14 at 14:32
  • @OliverGierke I noticed that Spring Data REST sets the allow methods header using org.springframework.http.HttpHeaders.ALLOW which is set to "Allow". According to this [W3C Recommendation](http://www.w3.org/TR/cors/#access-control-allow-methods-response-header), the header name should be Access-Control-Allow-Methods. Why is this discrepancy? – dimi Oct 03 '14 at 15:07
  • We currently simply implement the HTTP OPTIONS method as defined in the spec. – Oliver Drotbohm Oct 04 '14 at 09:19
0

Just set the parameter dispatchOptionsRequest to true into the dispatcher to process the Options method calls, into the implementation of the WebApplicationInitializer.

ServletRegistration.Dynamic dispatcher = container.addServlet("dispatcher", new DispatcherServlet(applicationContext));

dispatcher.setInitParameter("dispatchOptionsRequest", "true");                

dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/*");
Daniel De León
  • 13,196
  • 5
  • 87
  • 72