使用Tomcat和Springboot配置HTTPS时禁用异步支持

时间:2019-06-26 00:09:43

标签: java spring-boot spring-mvc spring-webflux

我目前正在使用启用了tomcat和HTTPS的Springboot 2.1应用程序。我们正在尝试使用spring-webflux提供的新的Reactive堆栈编写一些新的API。由于该应用程序仍然具有传统的阻塞端点,因此我们需要使用启用了异步支持的Tomcat才能使新的非阻塞API正常工作。

运行API并尝试通过HTTPS击中端点时,出现以下错误:

ERROR c.b.b.c.u.s.r.c.ApiExceptionHandler - Async support must be enabled on a servlet and for all filters involved in async request processing. This is done in Java code using the Servlet API or by adding "<async-supported>true</async-supported>" to servlet and filter declarations in web.xml.
java.lang.IllegalStateException: Async support must be enabled on a servlet and for all filters involved in async request processing. This is done in Java code using the Servlet API or by adding "<async-supported>true</async-supported>" to servlet and filter declarations in web.xml.

如果我禁用HTTPS并使用HTTP打API,则请求有效,并且从新的非阻塞API控制器获得响应。

当前使用以下代码配置HTTPS(如果我删除此配置,则非阻塞api有效):

@Configuration
public class Config implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {

    private final SslProperties sslProperties;
    private final LogbackAccessProperties logbackAccessProperties;

    public BootConfig(SslProperties sslProperties, LogbackAccessProperties logbackAccessProperties) {
        this.sslProperties = sslProperties;
        this.logbackAccessProperties = logbackAccessProperties;
    }

    @Override
    public void customize(TomcatServletWebServerFactory factory) {
        factory.addContextValves(getLogbackValve());
        factory.addConnectorCustomizers(connector -> {
            Http11NioProtocol proto = (Http11NioProtocol) connector.getProtocolHandler();
            proto.setSSLEnabled(true);
            connector.setScheme("https");
            connector.setSecure(true);
            proto.setKeystoreFile(sslProperties.getKeyStoreLocation());
            proto.setKeystorePass(sslProperties.getKeyStorePassword());
            proto.setKeystoreType(sslProperties.getKeyStoreType());
            proto.setTruststoreFile(sslProperties.getKeyStoreLocation());
            proto.setTruststorePass(sslProperties.getKeyStorePassword());
            proto.setTruststoreType(sslProperties.getKeyStoreType());
            proto.setKeyAlias(sslProperties.getHostingServerKeyAlias());
            proto.setSslEnabledProtocols("TLSv1.2");
        });
    }

    private LogbackValve getLogbackValve() {
        LogbackValve valve = new LogbackValve();
        valve.setFilename(logbackAccessProperties.getConfig());
        return valve;
    }
}

在线阅读我可以看到,当使用tomcat和async-supportedspring-boot-starter-webflux一起使用时,默认情况下Springboot启用spring-mvc。使用HTTP时似乎是这种情况,但是设置HTTPS似乎不再起作用。设置HTTPS时还有另一种方法可以启用它吗?

1 个答案:

答案 0 :(得分:0)

我最终找到了问题的原因。使用HTTPS不会导致此问题。我相信情况就是如此,因为当我删除public void customize(TomcatServletWebServerFactory factory) {...方法时,它就起作用了。

好像被添加的LogbackValve禁用了异步。必须使用asyncSupported=true设置阀门才能工作。所以我不得不将我的方法更新为:

    private LogbackValve getLogbackValve() {
        LogbackValve valve = new LogbackValve();
        valve.setFilename(logbackAccessProperties.getConfig());
        valve.setAsyncSupported(true); // This line fixed the issue
        return valve;
    }

从阅读文档来看,这不是很明显,所以花了我一段时间才弄清楚。如果有人遇到相同的问题,希望对您有所帮助:)