First off, I've read "How to handle HTTP OPTIONS with Spring MVC?" but the answers do not seem directly applicable to Spring Boot.
It looks like I should do this:
configure the dispatcherServlet by setting its
dispatchOptionsRequest
totrue
But how to do that, given that I have no XML configs, or any variety of DispatcherServlet
initializer class in my code (mentioned by this answer)?
In a @RestController
class, I have a method like this, which currently does not get invoked.
@RequestMapping(value = "/foo", method = RequestMethod.OPTIONS)
public ResponseEntity options(HttpServletResponse response) {
log.info("OPTIONS /foo called");
response.setHeader("Allow", "HEAD,GET,PUT,OPTIONS");
return new ResponseEntity(HttpStatus.OK);
}
Spring Boot 1.2.7.RELEASE; a simple setup not very different from that in Spring REST guide.
You could respond with an Allowed header and even document your API in the body. You could respond with additional CORS defined Access-Control-Request-* headers. You could respond with 405 Method Not Allowed or 501 Not Implemented .
The HTTP OPTIONS method requests permitted communication options for a given URL or server. A client can specify a URL with this method, or an asterisk ( * ) to refer to the entire server.
Starting with Spring Boot 1.3.0 this behavior can be configured using following property:
spring.mvc.dispatch-options-request=true
DispatcherServlet
DispatcherServlet
in Spring Boot is defined by DispatcherServletAutoConfiguration
. You can create your own DispatcherServlet
bean somewhere in your configuration classes, which will be used instead of the one in auto configuration:
@Bean(name = DispatcherServletAutoConfiguration.DEFAULT_DISPATCHER_SERVLET_BEAN_NAME) public DispatcherServlet dispatcherServlet() { DispatcherServlet dispatcherServlet = new DispatcherServlet(); dispatcherServlet.setDispatchOptionsRequest(true); return dispatcherServlet; }
But be aware that defining your DispatcherServlet
bean will disable the auto configuration, so you should manually define other beans declared in the autoconfiguration class, namely the ServletRegistrationBean
for DispatcherServlet
.
BeanPostProcessor
You can create BeanPostProcessor
implementation which will set the dispatchOptionsRequest
attribute to true
before the bean is initialized. Yoy can put this somewhere in your configuration classes:
@Bean public DispatcherServletBeanPostProcessor dispatcherServletBeanPostProcessor() { return new DispatcherServletBeanPostProcessor(); } public static class DispatcherServletBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof DispatcherServlet) { ((DispatcherServlet) bean).setDispatchOptionsRequest(true); } return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; } }
SpringBootServletInitializer
If you had SpringBootServletInitializer
in your application you could do something like this to enable OPTIONS dispatch:
public class ServletInitializer extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(Application.class); } @Override public void onStartup(ServletContext servletContext) throws ServletException { super.onStartup(servletContext); servletContext.getServletRegistration(DispatcherServletAutoConfiguration.DEFAULT_DISPATCHER_SERVLET_BEAN_NAME) .setInitParameter("dispatchOptionsRequest", "true"); } }
That would however only work if you deployed your app as a WAR into Servlet container, as the SpringBootServletInitializer
code is not executed when running your Spring Boot app using main
method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With