wake-up-neo.net

Wie gehe ich mit HTTP OPTIONS-Anfragen in Spring Boot um?

Zuerst habe ich gelesen " Wie gehe ich mit Spring MVC mit HTTP-OPTIONS um? ", aber die Antworten scheinen nicht direkt auf Spring Boot anwendbar zu sein.

Es sieht so aus, als sollte ich das tun:

konfigurieren Sie das dispatcherServlet, indem Sie dessen .__ einstellen. dispatchOptionsRequest zu true

Aber wie soll ich das machen, wenn ich keine XML-Configs oder eine andere DispatcherServlet Initializer-Klasse in meinem Code habe ( in dieser Antwort erwähnt )?

In einer @RestController-Klasse habe ich eine Methode wie diese, die derzeit nicht aufgerufen wird.

@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; Ein einfaches Setup unterscheidet sich nicht sehr von dem in Spring REST Guide .

22
Jonik

Option 1: Spring Boot-Eigenschaften (nur Spring Boot 1.3.0+)

Ab Spring Boot 1.3.0 kann dieses Verhalten mit folgender Eigenschaft konfiguriert werden:

spring.mvc.dispatch-options-request=true

Option 2: Benutzerdefinierte DispatcherServlet

DispatcherServlet in Spring Boot wird durch DispatcherServletAutoConfiguration definiert. Sie können irgendwo in Ihren Konfigurationsklassen Ihre eigene DispatcherServlet-Bean erstellen, die anstelle der in der automatischen Konfiguration verwendeten verwendet wird:

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

Beachten Sie jedoch, dass durch das Definieren Ihres DispatcherServlet-Beans die automatische Konfiguration deaktiviert wird. Sie sollten daher andere Beans, die in der Autokonfigurationsklasse deklariert sind, manuell definieren, nämlich ServletRegistrationBean für DispatcherServlet.

Option 3: BeanPostProcessor

Sie können eine BeanPostProcessor-Implementierung erstellen, die das dispatchOptionsRequest-Attribut auf true setzt, bevor die Bean initialisiert wird. Sie können dies irgendwo in Ihre Konfigurationsklassen einfügen:

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

Option 4: SpringBootServletInitializer

Wenn Sie SpringBootServletInitializer in Ihrer Anwendung hätten, könnten Sie so etwas tun, um den Versand von OPTIONS zu aktivieren:

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

Dies würde jedoch nur funktionieren, wenn Sie Ihre App als WAR im Servlet-Container bereitgestellt haben, da der SpringBootServletInitializer-Code nicht ausgeführt wird, wenn Sie Ihre Spring Boot-App mit der main-Methode ausführen.

21

Ich habe dieses Problem mit einer auf Spring Boot 1.3.x basierenden Rest-App ausgeführt, und während ich das Problem diagnostizierte, erlaubte ich meiner Spring Tool Suite, auf die neueste Version zu aktualisieren. 

Als ich in dem aktualisierten STS einen neuen Spring Boot RestController-Test erstellt habe, funktionierte er wie in der Dokumentation unter Spring 4.3 angekündigt. Mir fiel auf, dass die Maven-Abhängigkeit in der neuen Test-App auf Spring Boot 1.5.8 gesprungen war. Daher habe ich die Abhängigkeit für die alte App geändert, um sie auf Spring Boot 1.5.8/Spring 4.3.12 zu aktualisieren. Das Problem wurde behoben und nun funktioniert es wie angekündigt mit einer RequestMapping-Anmerkung, die ein Interesse an der Bearbeitung der OPTIONS-Anforderungen angibt ...

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

... sendet nun die OPTIONS-Anfrage an den Handler.

Wenn Sie also auf eine neuere Version von Spring aktualisieren können, müssen Sie keine besonderen Konfigurationen definieren, um die Behandlung der Anforderungsmethoden von OPTIONS zu aktivieren (Spring 4.3.12/Spring Boot 1.5.8).

0
beaudet