Come gestire le richieste HTTP OPTIONS in Spring Boot?

Innanzitutto, ho letto ” Come gestire le OPZIONI HTTP con Spring MVC? ” Ma le risposte non sembrano direttamente applicabili a Spring Boot.

Sembra che dovrei fare questo:

configurare il dispatcherServlet impostando il suo dispatchOptionsRequest su true

Ma come farlo , dato che non ho configurazioni XML, o nessuna varietà di classi di inizializzatori di DispatcherServlet nel mio codice ( menzionate da questa risposta )?

In una class @RestController , ho un metodo come questo, che al momento non viene richiamato.

 @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; una semplice configurazione non molto diversa da quella nella guida di REST di spring .

Opzione 1: proprietà Spring Boot (solo Spring Boot 1.3.0+)

A partire da Spring Boot 1.3.0 questo comportamento può essere configurato utilizzando la seguente proprietà:

 spring.mvc.dispatch-options-request=true 

Opzione 2: DispatcherServlet personalizzato

DispatcherServlet in Spring Boot è definito da DispatcherServletAutoConfiguration . È ansible creare il proprio bean DispatcherServlet da qualche parte nelle classi di configurazione, che verrà utilizzato al posto di quello in configurazione automatica:

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

Ma sappi che la definizione del tuo bean DispatcherServlet disabiliterà la configurazione automatica, quindi dovresti definire manualmente altri bean dichiarati nella class di autoconfigurazione, ovvero ServletRegistrationBean per DispatcherServlet .

Opzione 3: BeanPostProcessor

È ansible creare un’implementazione BeanPostProcessor che imposterà l’attributo dispatchOptionsRequest su true prima che il bean venga inizializzato. Yoy può metterlo da qualche parte nelle tue classi di configurazione:

 @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; } } 

Opzione 4: SpringBootServletInitializer

Se avevi SpringBootServletInitializer nella tua applicazione, puoi fare qualcosa di simile per abilitare la spedizione OPTIONS:

 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"); } } 

Tuttavia, ciò funzionerebbe solo se la tua app è stata distribuita come WAR nel contenitore Servlet, poiché il codice SpringBootServletInitializer non viene eseguito quando si esegue l’applicazione Spring Boot utilizzando il metodo main .

Mi sono imbattuto in questo problema con un’app di rest basata su Spring Boot 1.3.x e durante la diagnosi del problema ho permesso alla mia Spring Tool Suite di aggiornarsi alla versione più recente.

Quando ho creato un nuovo test Spring Boot RestController nel STS aggiornato, ha funzionato come la documentazione pubblicizza in Spring 4.3. Ho notato che la dipendenza da Maven era passata al boot primaverile 1.5.8 nella nuova app di test, quindi ho appena cambiato la dipendenza per la vecchia app per aggiornarla in spring boot 1.5.8 / spring 4.3.12. Questo ha risolto il problema e ora funziona come pubblicizzato con un’annotazione RequestMapping che specifica un interesse nella gestione delle richieste OPTIONS …

 @RequestMapping(value="/account/{id}", method={RequestMethod.OPTIONS,RequestMethod.GET}) 

… ora invia la richiesta OPTIONS al gestore.

Quindi, se sei in grado di aggiornare ad una versione successiva di Spring, non dovresti aver bisogno di definire alcuna configurazione speciale per abilitare la gestione del metodo di richiesta OPTIONS (Spring 4.3.12 / Spring Boot 1.5.8).