如何在运行在 Tomcat 上的 Spring Web 应用程序中使用 Spring 的响应式 WebClient

Posted

技术标签:

【中文标题】如何在运行在 Tomcat 上的 Spring Web 应用程序中使用 Spring 的响应式 WebClient【英文标题】:How to use Spring's reactive WebClient in a Spring Web Application which runs on Tomcat 【发布时间】:2019-09-15 08:10:31 【问题描述】:

无法在 Tomcat 上运行的基于 Spring Boot 的 Web 应用程序中使用 Spring 的响应式 WebClient。由于未解决的依赖关系,应用程序启动本身失败。

我查看了https://github.com/spring-projects/spring-boot/issues/9690,但不幸的是,这对我来说不是一个选项,因为我无法将 WebApplication 类型设置为 None

我的 gradle 文件:

dependencies 

    compile(group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa') 
        exclude(module: 'tomcat-juli')
    
    compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-redis'


    compile group: 'org.springframework.boot', name: 'spring-boot-starter-web'
    compile group: 'org.springframework.session', name: 'spring-session'

    compile group: 'org.hibernate', name: 'hibernate-java8'
    compile group: 'org.hibernate', name: 'hibernate-validator', version: '5.2.4.Final'

    compile group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-guava'
    compile group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-hibernate5'
    compile group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310'

    compile group: 'com.google.guava', name: 'guava'
    compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.3.2'
    compile group: 'org.postgresql', name: 'postgresql'

    compile group: 'io.jsonwebtoken', name: 'jjwt', version:'0.9.0'

    compile group: 'com.nimbusds', name: 'nimbus-jose-jwt', version:'5.12'

    // Spring managed dependency is not working, so resorted to using specific version
    // compile('org.springframework.boot:spring-boot-starter-webflux')
    compile group: 'org.springframework.boot', name: 'spring-boot-starter-webflux', version: '2.1.4.RELEASE'
    /*
    compile group: 'org.springframework', name: 'spring-web-reactive', version: '5.0.0.M1'
    compile group: 'org.springframework', name: 'spring-web', version: '5.1.6.RELEASE'
    */


    implementation 'com.auth0:jwks-rsa:0.7.0



bootRepackage 
    enabled = false


错误:

Caused by: java.lang.NoClassDefFoundError: org/springframework/http/client/reactive/ClientHttpConnector
        at org.springframework.web.reactive.function.client.WebClient.create(WebClient.java:144)

然后我尝试添加,

compile group: 'org.springframework', name: 'spring-web-reactive', version: '5.0.0.M1'

然后又抱怨别的事情,这让我补充了

compile group: 'org.springframework', name: 'spring-web', version: '5.1.6.RELEASE'

但是在启动我的应用程序时出现了另一个错误,这让我认为还有其他问题。

确切地说,我只是想从另一个微服务(基于 Spring Boot 的 Web 应用程序)中使用 Reactive WebClient 调用一个微服务。

使用 RestTemplate 效果很好,但我只是想尝试响应式 WebClient 并遇到错误。

由于我们托管依赖项的方式,托管依赖项无法正常工作。我们的依赖服务器无法解析它们。这就是具有特定版本的 Spring Boot 依赖项的原因

【问题讨论】:

【参考方案1】:

org.springframework.http.client.reactive.ClientHttpConnectorspring-web jar 的一部分,因此如果使用spring-boot-starter-webfluxspring-boot-starter-web,它应该可用。如果您正在编写基于传统 servlet 的应用程序,那么您应该使用 spring-boot-starter-web

检查gradle dependencies 的输出以确保您有一个spring-web jar。如果你这样做了,很可能它已经被损坏了,你应该清除你的 gradle 缓存。

我还建议您使用 Spring Boot 的 managed dependencies 而不是在每个依赖项上指定版本号。这将确保您获得已知可以很好地协同工作的版本。

【讨论】:

是的,我的是传统的基于 Servlet 的应用程序(Restful Web 服务)。 W.r.对于您关于使用 spring-boot-starter-web 的建议,它没有响应式 WebClient 试图用来从我的应用程序调用另一个微服务(graphql 端点) btw spring-boot-starter-webflux 没有下载Spring tutorial 中提到的所需反应类 请使用更全面的构建文件更新您的问题。由于您的问题暗示了几次不兼容的尝试,因此很难为您提供帮助。您指向的弹簧指南正在工作,它已通过 CI env 测试。 @BrianClozel 更新了我的问题并在此处上传了我的依赖项:gradle-dependencies.json。依赖项确实列出了spring-web,但我想知道为什么我仍然得到java.lang.NoClassDefFoundError: org/springframework/http/client/reactive/ClientHttpConnector

以上是关于如何在运行在 Tomcat 上的 Spring Web 应用程序中使用 Spring 的响应式 WebClient的主要内容,如果未能解决你的问题,请参考以下文章

部署在tomcat上的Spring Boot无法启动

如何在 spring-boot 中拦截嵌入式 Tomcat 上的“全局”404

在 Tomcat 10.x 上部署 Spring 5.x

在 Tomcat 10.x 上部署 Spring 5.x

Tomcat 上的 Spring Security/JSF/Hibernate 意外会话劫持?

Tomcat上的Spring Boot War部署不起作用