web-dev-qa-db-ja.com

Spring BootでHTTP OPTIONSリクエストを処理する方法は?

最初に、「 Spring MVCでHTTP OPTIONSを処理する方法 」を読みましたが、答えはSpring Bootに直接適用できないようです。

私はこれをする必要があるようです:

dispatchOptionsRequesttrueに設定してdispatcherServletを設定します

しかし、それを行う方法、XML構成、または私のコードにさまざまなDispatcherServlet初期化クラスがない場合、( この回答で言及 )?

@RestControllerクラスには、このようなメソッドがありますが、現在は呼び出されません。

@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; Spring REST guide の設定とそれほど変わらない単純な設定。

25
Jonik

オプション1:Spring Bootプロパティ(Spring Boot 1.3.0+のみ)

Spring Boot 1.3.0以降、この動作は次のプロパティを使用して設定できます。

spring.mvc.dispatch-options-request=true

オプション2:カスタムDispatcherServlet

Spring BootのDispatcherServletDispatcherServletAutoConfigurationで定義されます。構成クラスのどこかに、独自のDispatcherServlet Beanを作成できます。これは、自動構成のBeanの代わりに使用されます。

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

ただし、DispatcherServlet Beanを定義すると自動構成が無効になるため、自動構成クラスで宣言されている他のBean、つまりServletRegistrationBeanDispatcherServletを手動で定義する必要があります。

オプション3:BeanPostProcessor

Beanが初期化される前にBeanPostProcessor属性をdispatchOptionsRequestに設定するtrue実装を作成できます。 Yoyはあなたの設定クラスのどこかにこれを置くことができます:

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

オプション4:SpringBootServletInitializer

アプリケーションにSpringBootServletInitializerが含まれている場合は、次のようにして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");
    }
}

ただし、SpringBootServletInitializerメソッドを使用してSpring Bootアプリを実行するときにmainコードは実行されないため、アプリをWARとしてサーブレットコンテナにデプロイした場合にのみ機能します。

24

Spring Boot 1.3.xベースのレストアプリでこの問題に遭遇し、問題を診断しながら、Spring Tool Suiteを最新バージョンに更新することができました。

更新されたSTSで新しいテストSpring Boot RestControllerを作成したとき、ドキュメントがSpring 4.3でアドバタイズするように機能しました。新しいテストアプリでMaven依存関係がスプリングブート1.5.8にジャンプしたことに気付いたので、古いアプリの依存関係を変更して、スプリングブート1.5.8 /スプリング4.3.12に更新しました。これで問題が修正され、OPTIONSリクエストの処理への関心を指定するRequestMappingアノテーションでアドバタイズされるようになりました...

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

...これで、OPTIONS要求がハンドラーに送信されます。

そのため、Springの新しいバージョンに更新できる場合、OPTIONSリクエストメソッドの処理を有効にするために特別な構成を定義する必要はありません(Spring 4.3.12/Spring Boot 1.5.8)。

0
beaudet