标签: spring-webclient

微服务之间的通信:Spring cloud OpenFeign vs WebClient/RestTemplate

关于用于背靠背通信的最佳方式有什么想法吗?

Spring Cloud OpenFeign还是WebClient/RestTemplate

我认为Spring Cloud Gateway需要时应该使用Feign客户端

与其他微服务通信,而WebClient/RestTemplate应该用于背对背通信。

我错了吗 ?

resttemplate spring-cloud spring-webclient openfeign

3
推荐指数
1
解决办法
3774
查看次数

java.lang.ClassNotFoundException:com.sun.xml.internal.bind.v2.ContextFactory

\n

春季启动版本2.4.4

\n

Java版本15

\n
\n
@Bean\n    public WebClient webClient() {\n        return WebClient.builder().baseUrl(BASE_URL)\n                .defaultHeaders(header -> header.setBasicAuth("test",\n                        "testpwd"))\n                .clientConnector(new ReactorClientHttpConnector(HttpClient.newConnection()))\n                .exchangeStrategies(ExchangeStrategies.builder().codecs(configurer -> {\n                    configurer.defaultCodecs().jaxb2Encoder(new Jaxb2XmlEncoder());\n                    configurer.defaultCodecs().jaxb2Decoder(new Jaxb2XmlDecoder());\n                }).build()).build();\n        \n    }\n
Run Code Online (Sandbox Code Playgroud)\n

使用 Spring boot 2.4.4 webclient 并尝试使用 XML 响应来使用服务。

\n
public Mono<ServerResponse> retrieveServices() {\n\n        // Headers can be passed here or while building the client\n        Mono<DirectoryOfService> serviceMono = webClient\n             .get().uri("/api/v1/test/services")\n            .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE)\n            .accept(MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML)\n            .retrieve().bodyToMono(DirectoryOfService.class);\n\n    }\n
Run Code Online (Sandbox Code Playgroud)\n

错误:-

\n
    org.springframework.core.codec.CodecException: Could not create JAXBContext for class [class com.test.model.DirectoryOfService]: Implementation of JAXB-API …
Run Code Online (Sandbox Code Playgroud)

java spring spring-boot spring-webflux spring-webclient

3
推荐指数
1
解决办法
2万
查看次数

Spring WebClient如何在INFO级别记录每次重试?

我有以下 WebClient - 对 localhost:8090 进行 http 调用 - 定义了 bean:

@Configuration
class WebClientConfig {
    @Bean
    public WebClient webClientBean() {
        return WebClient.create("http://localhost:8090");
    }
}
Run Code Online (Sandbox Code Playgroud)

并调用另一个服务(8090):

Response response = requestBodySpec
        .retrieve()
        .bodyToMono(Response.class)
        .timeout(Duration.ofSeconds(5))
        .retry(2L)
        .doOnSuccess(res -> log.info(res))
        .doOnError(err -> log.error(err))
        .block();
Run Code Online (Sandbox Code Playgroud)

超时后我看到错误:

java.util.concurrent.TimeoutException:在“flatMap”中 5000 毫秒内没有观察到任何项目或终端信号

但我没有看到我指定的另外 2 次重试的日志;它们仅在我打开 TRACE 时可见:

跟踪 2120 --- [nio-8080-exec-1] oswrfclient.ExchangeFunctions : [9c7e1e0] HTTP POST http://localhost:8090/test, headers={masked}

有什么方法可以在重试发生时记录事件吗?与上面的日志类似,除了我必须 INFO 记录它。

spring spring-boot spring-webflux spring-webclient

3
推荐指数
1
解决办法
2923
查看次数

如何在java中对Spring WebClient进行单元测试?

我有这段代码,它使用 WebClient 调用第三方 API。

    public Mono<JsonNode> callApi(String url) {
        return webClient.get()
                .uri(url)
                .headers(httpHeaders -> httpHeaders.set(Constants.X_API_KEY, apiKey))
                .retrieve()
                .onStatus(HttpStatus::is5xxServerError,
                        res -> {
                            res.bodyToMono(String.class)
                                    .subscribe(e -> log.error(Constants.EXCEPTION_LOG, e));
                            return Mono.error(new RetryableException("Server error: " + res.rawStatusCode()));
                        })
                .onStatus(HttpStatus::is4xxClientError,
                        res -> {
                            res.bodyToMono(String.class)
                                    .subscribe(e -> log.error("Exception occurred in callPartnerApi: No retries {}", e));
                            return Mono.error(new Exception("Exception occurred calling partner api, no retries " + res.rawStatusCode()));
                        })
                .bodyToMono(JsonNode.class);
    }
Run Code Online (Sandbox Code Playgroud)

我正在尝试使用 Mockito 对此进行单元测试,到目前为止我的测试失败了:

    @Test
    void testCallPartnerApi_then5xxException() {
        WebClient.RequestHeadersUriSpec requestHeadersUriSpec = mock(WebClient.RequestHeadersUriSpec.class);
        WebClient.RequestHeadersSpec requestHeadersSpec = mock(WebClient.RequestHeadersSpec.class);
        WebClient.ResponseSpec …
Run Code Online (Sandbox Code Playgroud)

java junit mockito spring-webflux spring-webclient

3
推荐指数
1
解决办法
4964
查看次数

WebClient 上的 Exchange() 会抛出哪些异常?

我已经实现了一个服务,它使 ReST 调用其他服务来实现其部分功能。我正在使用反应式WebClient,例如:

webClient.post()
    .uri(....)
    .contentType(....)
    .accept(....)
    .header(....)
    .syncBody(someRequestObject)
    .exchange()
    .flatMap(someResponseHandler::handleResponse)
    .doOnError(throwable -> {
        // do interesting things depending on throwable
    })
    .retry(1, this::somePredicateDependingOnThrowable);
Run Code Online (Sandbox Code Playgroud)

现在...我处理 HTTP 状态someResponseHandler::handleResponse,但我真正想知道的是,还有哪些其他类型的异常/错误exchange()- 即

  • 如果我根本无法连接到下游服务,会出现什么异常/错误?
  • 如果连接尝试超时,我会收到哪些异常/错误?
  • 如果我可以连接,但请求在收到响应之前超时,会出现什么异常/错误?

显然,这些都不是 HTTP 状态代码 - 但我找不到任何文档来告诉我可以查找什么。我只是没有找对地方吗?我浏览了反应式 WebClient 的文档,也浏览了 Reactor Netty 参考指南,但没有成功。

对于背景来说,这很重要,因为我们进行基于 HATEOAS 的服务发现 - 对于其中一些异常,我想触发重新发现,对于其中一些,我不想。

reactor-netty spring-webclient

2
推荐指数
1
解决办法
3009
查看次数

WebClient 从订阅返回值

我尝试使用 webclient 非阻塞方法验证验证码响应。所以它的工作,但我需要我的方法返回布尔值而不是异常。我如何从订阅返回值?

        webClient
                .post()
                .uri(verifyUri)
                .exchange()
                .flatMap(res -> res.bodyToMono(GoogleResponse.class))
                .doOnError(e -> log.error("Request error"))
                .subscribe(GoogleResponse -> {
                    try {
                        log.debug("Google response: {}", GoogleResponse);
                        if (!GoogleResponse.isSuccess()) {
                            throw new ReCaptchaInvalidException("reCaptcha response is not valid");
                        }
                    } catch (ReCaptchaInvalidException e) {
                        throw new ReCaptchaUnavailableException("Registration unavailable at this time.  Please try again later.", e);
                    }
                });
Run Code Online (Sandbox Code Playgroud)

java spring-boot spring-webclient

2
推荐指数
1
解决办法
1万
查看次数

在转换方法 WebFlux 中从 lambda 返回 null 或可空的东西

在 Spring WebFlux 链中,我使用了有时可能返回 null 的映射操作,并且我收到警告:
Return null or something nullable from lambda in transformation mehtod
我相信当数据为空时,它实际上不会将输入映射到,null但会引发异常。
处理这种情况的最佳方法是什么?

可为空的 Map 方法:

public Pojo parseJson(String json) {
    try {
        // parse 
        return pojo;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}
Run Code Online (Sandbox Code Playgroud)

我的反应链:

public Mono<Pojo> query(long id) {

    Integer value = idMapper.getValue(id);

    if (value != null) {
        return repo.query(value)

                        Parse Method
                             |
                             v
                .map(this::parse);
    }
    return null;
}
Run Code Online (Sandbox Code Playgroud)

java spring reactive spring-webflux spring-webclient

2
推荐指数
1
解决办法
3274
查看次数

Webclient + Jackson:如何设置反序列化将snake_case 转换为camelCase?

我想避免必须为我的属性加上前缀@JsonProperty("property_name"),而只是设置 Spring WebClient 构建器以将所有 snake_cases 转换为 camelCases。

那可能吗?

java jackson spring-webclient

2
推荐指数
1
解决办法
3652
查看次数

为什么 WebFlux-WebClient 超时不起作用?

我正在使用 Spring boot Webflux 2.4.4(最新)并尝试使用 WebClient 调用后端 URL。WebClient 总是响应超过 20 秒。如果我直接点击 URL,它会以毫秒为单位响应。

Pom 看起来如下:

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.projectreactor</groupId>
            <artifactId>reactor-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
Run Code Online (Sandbox Code Playgroud)

代码如下所示:

@RestController
public class Controller {

    @GetMapping("/test")
    public Mono<String> test() {

        long startMillis = System.currentTimeMillis();
        return webClient().get().uri("https://www.google.com").exchangeToMono(response -> {
            System.out.println("Elapsed Time is:  " + (System.currentTimeMillis() - startMillis));
            if (response.statusCode().equals(HttpStatus.OK)) {
                return Mono.just("OK");
            }
            return Mono.just("OK");
        });
    }

    private WebClient webClient() {
        return WebClient.builder()
                .clientConnector(new ReactorClientHttpConnector(HttpClient
                        .create().secure().responseTimeout(Duration.ofMillis(1000))
                        .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 3000).doOnConnected(c -> c …
Run Code Online (Sandbox Code Playgroud)

java netty spring-boot spring-webflux spring-webclient

2
推荐指数
1
解决办法
324
查看次数

SpringBoot FeignClient 与 WebClient

我想消耗一些休息服务。之前用过 RestTemplate,现在想知道 SpringBoot FeignClient 和 WebClient 的主要区别是什么?什么时候应该使用它们?

spring-boot spring-webclient reactive-feign-client

2
推荐指数
2
解决办法
1753
查看次数