I'm trying to enable CORS in a sample project using Spring Boot 1.3.3
I try to follow all the instructions from this link however I still not able to see results.
In my Application.java I have the following code.
@SpringBootApplication
public class Application {
private static final String[] REQUEST_METHOD_SUPPORTED = { "GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS", "HEAD" };
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/rest/**").allowedOrigins("*").allowedHeaders("*").allowedMethods(REQUEST_METHOD_SUPPORTED);
}
};
}
}
Everything works when I use GET
and POST
, but when I try to use PUT
, DELETE
, OPTIONS
or PATCH
. Also, I try to add this property spring.mvc.dispatch-options-request:true
but still I don't get it work
I'm getting the following error:
Resolving exception from handler [null]: org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'OPTIONS' not supported
Invoking @ExceptionHandler method: public final org.springframework.http.ResponseEntity<java.lang.Object> org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler.handleException(java.lang.Exception,org.springframework.web.context.request.WebRequest)
Request method 'OPTIONS' not supported
Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
Successfully completed request
Do you guys have an idea how can I solved this issue? Do you have a tutorial where I can see a sample working with CORS using PUT
or PATCH
?
--- UPDATE ---
Here is my controller
@RestController
@RequestMapping(value = "/api/rest/accounts", produces = MediaType.APPLICATION_JSON_VALUE)
public class AccountRestController {
private static final Logger LOGGER = LoggerFactory.getLogger(AccountRestController.class);
@RequestMapping(method = RequestMethod.POST)
public Account createAccount(@RequestBody Account messageBody) {
Account account = buildAccount(messageBody);
return dbPersistAccount(account);
}
@RequestMapping(method = RequestMethod.DELETE, value = "/{id}")
public void deleteAccount(@PathVariable("id") String id) {
dbRemoveAccount(id);
}
@RequestMapping(method = RequestMethod.PUT, value = "/{id}")
public void updateAccount(@PathVariable("id") String id, @RequestBody Account messageBody) {
Account account = dbGetAccount(id);
if (account == null) {
throw new ResourceNotFoundException("Account not found with id=[" + id + "]");
}
}
@RequestMapping(method = RequestMethod.PATCH, value = "/{id}")
public void markAccount(@PathVariable("id") String id) {
Account account = dbGetAccount(id);
if (account == null) {
throw new ResourceNotFoundException("Account not found with id=[" + id + "]");
}
}
@RequestMapping(method = RequestMethod.GET, value = "/{id}")
public Account getAccount(@PathVariable("id") String id) {
Account account = dbGetAccount(id);
if (account == null) {
throw new ResourceNotFoundException("Account not found with id=[" + id + "]");
}
return account;
}
}
Do I need to create the method OPTIONS manually? I don't have in my controller a method that handles the OPTIONS request
Thanks for your answers and comments.
At the end the answer has to be with a combination of the answers posted in here; we were getting consume by a client that did not send a content-type so we were getting a 403 when it try to do a OPTIONS before a PATCH or PUT; after the rest client sent a content-type we were able to handle the request.
So, in my case the following code works, if the request includes content-type and you don't need to do any work around.
However, if somebody has the requirement to allow requests OPTIONS without content-type, you need to use a simple filter which is mentioned in this Simple CORS Filter and change the following line:
response.setHeader("Access-Control-Allow-Headers", "");
I hope this can help somebody in the future.