Spring Webclient 有时不读取 204 响应

问题描述

我正在使用 Spring WebClient 调用内部 API,但有时我的 webClient 不分析响应代码并停留在“exchangetoMono”方法上并等待。

我使用:

我迁移到 spring-boot-starter-parent 2.5.2。在我使用交换之前,但它现在已被弃用,我认为这是我的问题

我没有尝试的一个解决方案是使用 OpenFeign

我的网络客户端配置:

Builder builder = WebClient.builder()
                .codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(16 * 1024 * 1024))
                //.exchangeStrategies(strategies)
                .clientConnector(httpProxyClientConnector(baseUrl))
                .baseUrl(baseUrl)
                .filter(filter)
                .filter(new LoggingExchangeFilterFunction());
        if (apiKey.isPresent()) {
            builder = builder.defaultHeader(X_API_KEY,apiKey.get());
        }
        return builder
                .defaultHeader(ACCEPT,APPLICATION_JSON_VALUE)
                .defaultHeader(CONTENT_TYPE,APPLICATION_JSON_VALUE) // all exchanges are JSON
                .build();

httpProxyClientConnectorMethod :

new ReactorClientHttpConnector(
                    HttpClient.create()
                            .compress(true)
                            .wiretap(true)
                            .proxy(typespec ->
                                            typespec
                                                    .type(HTTP)
                                                    .host(httpProxyHost)
                                                    .port(httpProxyPort)));

网络客户端调用

WebClient.get()
                .uri(uriBuilder ->
                        {
                            UriBuilder uri = uriBuilder.path("/v2/period").queryParam("from",from.format(FLATTENED_DATE_FORMAT))

                            return uri.build();
                        }
                )
                .exchangetoMono(clientResponse -> {
                    HttpStatus status = clientResponse.statusCode();
                    //Retry as response is being processed by api
                    if (ACCEPTED.equals(status)) {
                        return Mono.error(new EnqueuedRequest());
                    }
                    if (ApiFallbackUtils.getAllErrorStatus().contains(status)) {
                        return Mono.error(ApiFallbackUtils.getException(status));
                    }
                    if(status.equals(NO_CONTENT)){
                        Mono.just(emptyList());
                    }
                    return clientResponse.bodyToMono(DateKpi.class);
                })
                .retrywhen(Retry.fixedDelay(retryValue,ofMillis(delayValue)).filter(e -> e instanceof EnqueuedRequest))
                .onErrorResume(throwable -> ApiFallbackUtils.returnFallback(new DateKpi(),throwable));

错误日志:

[reactor-http-nio-4] [DEBUG] 2021-07-02 17:15:12.350 io.netty.util.internal.logging.Log4J2Logger: [id:e80c6acf-2,L:64171 - R:proxy-internet.org:3128] READ: 913B
         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| 48 54 54 50 2f 31 2e 31 20 32 30 34 20 0d 0a 44 |HTTP/1.1 204 ..D|
|00000010| 61 74 65 3a 20 46 72 69 2c 20 30 32 20 4a 75 6c |ate: Fri,02 Jul|
|00000020| 20 32 30 32 31 20 31 35 3a 31 35 3a 31 32 20 47 | 2021 15:15:12 G|
|00000030| 4d 54 0d 0a 53 65 72 76 65 72 3a 20 41 70 61 63 |MT..Server: Apac|
|00000040| 68 65 0d 0a 58 2d 43 6f 72 72 65 6c 61 74 69 6f |he..X-Correlatio|
|00000050| 6e 2d 49 64 3a 20 33 63 37 39 38 35 63 63 2d 63 |n-Id: 3c7985cc-c|
|00000060| 35 34 61 2d 34 33 35 32 2d 62 39 38 35 2d 63 63 |54a-4352-b985-cc|
|00000070| 63 35 34 61 33 33 35 32 39 39 0d 0a 58 2d 52 65 |c54a335299..X-Re|
|00000080| 71 75 65 73 74 2d 49 64 3a 20 33 63 37 39 38 35 |quest-Id: 3c7985|
|00000090| 63 63 2d 63 35 34 61 2d 34 33 35 32 2d 62 39 38 |cc-c54a-4352-b98|
|000000a0| 35 2d 63 63 63 35 34 61 33 33 35 32 39 39 0d 0a |5-ccc54a335299..|
|000000b0| 43 61 63 68 65 2d 43 6f 6e 74 72 6f 6c 3a 20 6e |Cache-Control: n|
|000000c0| 6f 2d 63 61 63 68 65 2c 20 6e 6f 2d 73 74 6f 72 |o-cache,no-stor|
|000000d0| 65 2c 20 6d 61 78 2d 61 67 65 3d 30 2c 20 6d 75 |e,max-age=0,mu|
|000000e0| 73 74 2d 72 65 76 61 6c 69 64 61 74 65 0d 0a 43 |st-revalidate..C|
|000000f0| 6f 6e 74 65 6e 74 2d 54 79 70 65 3a 20 61 70 70 |ontent-Type: app|
|00000100| 6c 69 63 61 74 69 6f 6e 2f 6a 73 6f 6e 3b 63 68 |lication/json;ch|
|00000110| 61 72 73 65 74 3d 55 54 46 2d 38 0d 0a 45 78 70 |arset=UTF-8..Exp|
|00000120| 69 72 65 73 3a 20 30 0d 0a 50 72 61 67 6d 61 3a |ires: 0..Pragma:|
|00000130| 20 6e 6f 2d 63 61 63 68 65 0d 0a 58 2d 43 6f 6e | no-cache..X-Con|
|00000140| 74 65 6e 74 2d 54 79 70 65 2d 4f 70 74 69 6f 6e |tent-Type-Option|
|00000150| 73 3a 20 6e 6f 73 6e 69 66 66 0d 0a 58 2d 46 72 |s: nosniff..X-Fr|
|00000160| 61 6d 65 2d 4f 70 74 69 6f 6e 73 3a 20 44 45 4e |ame-Options: DEN|
|00000170| 59 0d 0a 58 2d 58 53 53 2d 50 72 6f 74 65 63 74 |Y..X-XSS-Protect|
|00000180| 69 6f 6e 3a 20 31 3b 20 6d 6f 64 65 3d 62 6c 6f |ion: 1; mode=blo|
|00000190| 63 6b 0d 0a 56 69 61 3a 20 31 2e 31 20 61 70 69 |ck..Via: 1.1 api|
|000001a0| 2e 64 65 63 61 74 68 6c 6f 6e 2e 6e 65 74 2c 20 |.test.net,|
|000001b0| 31 2e 31 20 67 6f 6f 67 6c 65 0d 0a 41 6c 74 2d |1.1 google..Alt-|
|000001c0| 53 76 63 3a 20 63 6c 65 61 72 0d 0a 53 65 74 2d |Svc: clear..Set-|
|000001d0| 43 6f 6f 6b 69 65 3a 20 76 69 73 69 64 5f 69 6e |Cookie: visid_in|
|000001e0| 63 61 70 5f 32 34 31 30 36 32 30 3d 2f 69 63 69 |cap_2410620=/ici|
|000001f0| 51 69 55 59 54 48 43 55 32 34 75 5a 4b 30 5a 6e |QiUYTHCU24uZK0Zn|
|00000200| 67 6f 41 74 33 32 41 41 41 41 41 41 51 55 49 50 |goAt32AAAAAAQUIP|
|00000210| 41 41 41 41 41 41 44 77 49 54 67 4e 4e 71 33 49 |AAAAAADwITgNNq3I|
|00000220| 79 75 45 4e 49 37 32 63 2b 6c 65 4d 3b 20 65 78 |yuENI72c+leM; ex|
|00000230| 70 69 72 65 73 3d 53 61 74 2c 20 30 32 20 4a 75 |pires=Sat,02 Ju|
|00000240| 6c 20 32 30 32 32 20 30 37 3a 35 30 3a 34 36 20 |l 2022 07:50:46 |
|00000250| 47 4d 54 3b 20 48 74 74 70 4f 6e 6c 79 3b 20 70 |GMT; HttpOnly; p|
|00000260| 61 74 68 3d 2f 3b 20 44 6f 6d 61 69 6e 3d 2e 64 |ath=/; Domain=.d|
|00000270| 65 63 61 74 68 6c 6f 6e 2e 6e 65 74 0d 0a 53 65 |test.net..Se.   |
|00000280| 74 2d 43 6f 6f 6b 69 65 3a 20 69 6e 63 61 70 5f |t-Cookie: incap_|
|00000290| 73 65 73 5f 31 33 36 34 5f 32 34 31 30 36 32 30 |ses_1364_2410620|
|000002a0| 3d 57 57 70 4b 61 4d 4e 67 74 67 76 72 70 4d 33 |=WWpKaMNgtgvrpM3|
|000002b0| 61 2f 65 62 74 45 6f 41 74 33 32 41 41 41 41 41 |a/ebtEoAt32AAAAA|
|000002c0| 41 52 4d 4b 62 6a 6d 43 62 39 77 68 4e 5a 4b 49 |ARMKbjmCb9whNZKI|
|000002d0| 39 34 35 37 6a 7a 51 3d 3d 3b 20 70 61 74 68 3d |9457jzQ==; path=|
|000002e0| 2f 3b 20 44 6f 6d 61 69 6e 3d 2e 64 65 63 61 74 |/; Domain=.     |
|000002f0| 68 6c 6f 6e 2e 6e 65 74 0d 0a 58 2d 43 44 4e 3a |test.net..X-CDN:|
|00000300| 20 49 6d 70 65 72 76 61 0d 0a 43 6f 6e 74 65 6e | Imperva..Conten|
|00000310| 74 2d 45 6e 63 6f 64 69 6e 67 3a 20 67 7a 69 70 |t-Encoding: gzip|
|00000320| 0d 0a 54 72 61 6e 73 66 65 72 2d 45 6e 63 6f 64 |..Transfer-Encod|
|00000330| 69 6e 67 3a 20 63 68 75 6e 6b 65 64 0d 0a 58 2d |ing: chunked..X-|
|00000340| 49 69 6e 66 6f 3a 20 31 32 2d 36 37 33 36 30 35 |Iinfo: 12-673605|
|00000350| 39 32 2d 36 37 31 30 36 33 38 30 20 70 4e 59 4e |92-67106380 pNYN|
|00000360| 20 52 54 28 31 36 32 35 32 33 38 39 30 36 39 36 | RT(162523890696|
|00000370| 35 20 35 37 30 31 29 20 71 28 30 20 30 20 30 20 |5 5701) q(0 0 0 |
|00000380| 2d 31 29 20 72 28 31 20 31 29 20 55 35 0d 0a 0d |-1) r(1 1) U5...|
|00000390| 0a                                              |.               |
+--------+-------------------------------------------------+----------------+
[piloting] [reactor-http-nio-4] [DEBUG] 2021-07-02 17:15:12.350 io.netty.util.internal.logging.Log4J2Logger: [id:e80c6acf-2,L::64171 - R:proxy-internet.org:3128] READ: 5B
         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| 30 0d 0a 0d 0a                                  |0....           |
+--------+-------------------------------------------------+----------------+
[piloting] [reactor-http-nio-4] [DEBUG] 2021-07-02 17:15:12.351 io.netty.util.internal.logging.Log4J2Logger: [id:e80c6acf-2,L::64171 - R:proxy-internet.org:3128] READ COMPLETE
[piloting] [http-nio-8090-exec-7] [DEBUG] 2021-07-02 17:16:03.307 org.springframework.web.reactive.function.client.ExchangeFunctions$DefaultExchangeFunction: [260ad3b0] Cancel signal (to close connection)
[piloting] [reactor-http-nio-4] [DEBUG] 2021-07-02 17:16:03.307 io.netty.util.internal.logging.Log4J2Logger: [id:e80c6acf-2,L:64171 - R:proxy-internet.org:3128] CLOSE

退出没有错误

 [piloting] [reactor-http-nio-4] [DEBUG] 2021-07-02 17:15:06.996 io.netty.util.internal.logging.Log4J2Logger: [id:e80c6acf-1,L:/:64171 - R:proxy-internet.org:3128] READ: 1131B
          +-------------------------------------------------+
          |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
 +--------+-------------------------------------------------+----------------+
 |00000000| 48 54 54 50 2f 31 2e 31 20 32 30 34 20 0d 0a 44 |HTTP/1.1 204 ..D|
 |00000010| 61 74 65 3a 20 46 72 69 2c 20 30 32 20 4a 75 6c |ate: Fri,02 Jul|
 |00000020| 20 32 30 32 31 20 31 35 3a 31 35 3a 30 37 20 47 | 2021 15:15:07 G|
 |00000030| 4d 54 0d 0a 53 65 72 76 65 72 3a 20 41 70 61 63 |MT..Server: Apac|
 |00000040| 68 65 0d 0a 58 2d 43 6f 72 72 65 6c 61 74 69 6f |he..X-Correlatio|
 |00000050| 6e 2d 49 64 3a 20 32 35 37 64 30 64 30 32 2d 61 |n-Id: 257d0d02-a|
 |00000060| 37 66 34 2d 34 33 30 36 2d 62 64 30 64 2d 30 32 |7f4-4306-bd0d-02|
 |00000070| 61 37 66 34 61 33 30 36 35 66 0d 0a 58 2d 52 65 |a7f4a3065f..X-Re|
 |00000080| 71 75 65 73 74 2d 49 64 3a 20 32 35 37 64 30 64 |quest-Id: 257d0d|
 |00000090| 30 32 2d 61 37 66 34 2d 34 33 30 36 2d 62 64 30 |02-a7f4-4306-bd0|
 |000000a0| 64 2d 30 32 61 37 66 34 61 33 30 36 35 66 0d 0a |d-02a7f4a3065f..|
 |000000b0| 43 61 63 68 65 2d 43 6f 6e 74 72 6f 6c 3a 20 6e |Cache-Control: n|
 |000000c0| 6f 2d 63 61 63 68 65 2c 20 6e 6f 2d 73 74 6f 72 |o-cache,no-stor|
 |000000d0| 65 2c 20 6d 61 78 2d 61 67 65 3d 30 2c 20 6d 75 |e,mu|
 |000000e0| 73 74 2d 72 65 76 61 6c 69 64 61 74 65 0d 0a 43 |st-revalidate..C|
 |000000f0| 6f 6e 74 65 6e 74 2d 54 79 70 65 3a 20 61 70 70 |ontent-Type: app|
 |00000100| 6c 69 63 61 74 69 6f 6e 2f 6a 73 6f 6e 3b 63 68 |lication/json;ch|
 |00000110| 61 72 73 65 74 3d 55 54 46 2d 38 0d 0a 45 78 70 |arset=UTF-8..Exp|
 |00000120| 69 72 65 73 3a 20 30 0d 0a 50 72 61 67 6d 61 3a |ires: 0..Pragma:|
 |00000130| 20 6e 6f 2d 63 61 63 68 65 0d 0a 53 65 72 76 65 | no-cache..Serve|
 |00000140| 72 2d 54 69 6d 69 6e 67 3a 20 64 74 52 70 69 64 |r-Timing: dtRpid|
 |00000150| 3b 64 65 73 63 3d 22 2d 35 30 33 37 39 39 30 32 |;desc="-50379902|
 |00000160| 33 22 0d 0a 58 2d 43 6f 6e 74 65 6e 74 2d 54 79 |3"..X-Content-Ty|
 |00000170| 70 65 2d 4f 70 74 69 6f 6e 73 3a 20 6e 6f 73 6e |pe-Options: nosn|
 |00000180| 69 66 66 0d 0a 58 2d 46 72 61 6d 65 2d 4f 70 74 |iff..X-Frame-Opt|
 |00000190| 69 6f 6e 73 3a 20 44 45 4e 59 0d 0a 58 2d 4f 6e |ions: DENY..X-On|
 |000001a0| 65 41 67 65 6e 74 2d 4a 53 2d 49 6e 6a 65 63 74 |eAgent-JS-Inject|
 |000001b0| 69 6f 6e 3a 20 74 72 75 65 0d 0a 58 2d 58 53 53 |ion: true..X-XSS|
 |000001c0| 2d 50 72 6f 74 65 63 74 69 6f 6e 3a 20 31 3b 20 |-Protection: 1; |
 |000001d0| 6d 6f 64 65 3d 62 6c 6f 63 6b 0d 0a 53 65 74 2d |mode=block..Set-|
 |000001e0| 43 6f 6f 6b 69 65 3a 20 64 74 43 6f 6f 6b 69 65 |Cookie: dtCookie|
 |000001f0| 3d 76 5f 34 5f 73 72 76 5f 34 5f 73 6e 5f 37 43 |=v_4_srv_4_sn_7C|
 |00000200| 44 32 30 41 42 43 38 44 38 42 38 45 30 36 37 35 |D20ABC8D8B8E0675|
 |00000210| 41 30 35 42 43 41 37 38 37 38 35 38 43 38 5f 70 |A05BCA787858C8_p|
 |00000220| 65 72 63 5f 31 30 30 30 30 30 5f 6f 6c 5f 30 5f |erc_100000_ol_0_|
 |00000230| 6d 75 6c 5f 31 5f 61 70 70 2d 33 41 65 61 37 63 |mul_1_app-3Aea7c|
 |00000240| 34 62 35 39 66 32 37 64 34 33 65 62 5f 31 3b 20 |4b59f27d43eb_1; |
 |00000250| 50 61 74 68 3d 2f 3b 20 44 6f 6d 61 69 6e 3d 2e |Path=/; Domain=.|
 |00000260| 64 65 63 61 74 68 6c 6f 6e 2e 6e 65 74 0d 0a 56 |test.net..V     |
 |00000270| 69 61 3a 20 31 2e 31 20 61 70 69 2e 64 65 63 61 |ia: 1.1 api.test|
 |00000280| 74 68 6c 6f 6e 2e 6e 65 74 2c 20 31 2e 31 20 67 |      .net,1.1 g|
 |00000290| 6f 6f 67 6c 65 0d 0a 41 6c 74 2d 53 76 63 3a 20 |oogle..Alt-Svc: |
 |000002a0| 63 6c 65 61 72 0d 0a 53 65 74 2d 43 6f 6f 6b 69 |clear..Set-Cooki|
 |000002b0| 65 3a 20 76 69 73 69 64 5f 69 6e 63 61 70 5f 32 |e: visid_incap_2|
 |000002c0| 34 31 30 36 32 30 3d 5a 64 7a 5a 47 64 48 77 53 |410620=ZdzZGdHwS|
 |000002d0| 53 4b 4a 48 59 48 50 51 6f 70 42 57 58 73 74 33 |SKJHYHPQopBWXst3|
 |000002e0| 32 41 41 41 41 41 41 51 55 49 50 41 41 41 41 41 |2AAAAAAQUIPAAAAA|
 |000002f0| 41 43 5a 72 38 4d 75 70 6f 41 59 6c 38 4a 63 61 |ACZr8MupoAYl8Jca|
 |00000300| 54 67 46 54 49 76 53 3b 20 65 78 70 69 72 65 73 |TgFTIvS; expires|
 |00000310| 3d 53 61 74 2c 20 30 32 20 4a 75 6c 20 32 30 32 |=Sat,02 Jul 202|
 |00000320| 32 20 30 37 3a 35 30 3a 34 36 20 47 4d 54 3b 20 |2 07:50:46 GMT; |
 |00000330| 48 74 74 70 4f 6e 6c 79 3b 20 70 61 74 68 3d 2f |HttpOnly; path=/|
 |00000340| 3b 20 44 6f 6d 61 69 6e 3d 2e 64 65 63 61 74 68 |; Domain=.test  |
 |00000350| 6c 6f 6e 2e 6e 65 74 0d 0a 53 65 74 2d 43 6f 6f |   .net..Set-Coo|
 |00000360| 6b 69 65 3a 20 69 6e 63 61 70 5f 73 65 73 5f 31 |kie: incap_ses_1|
 |00000370| 33 36 34 5f 32 34 31 30 36 32 30 3d 7a 63 6e 6b |364_2410620=zcnk|
 |00000380| 57 35 6f 65 58 46 49 67 6d 73 33 61 2f 65 62 74 |W5oeXfigms3a/ebt|
 |00000390| 45 6e 73 74 33 32 41 41 41 41 41 41 34 2b 73 6c |Enst32AAAAAA4+sl|
 |000003a0| 75 33 37 41 69 64 4e 39 74 63 4a 45 39 6a 30 55 |u37AidN9tcJE9j0U|
 |000003b0| 63 51 3d 3d 3b 20 70 61 74 68 3d 2f 3b 20 44 6f |cQ==; path=/; Do|
 |000003c0| 6d 61 69 6e 3d 2e 64 65 63 61 74 68 6c 6f 6e 2e |main=.test.     |
 |000003d0| 6e 65 74 0d 0a 58 2d 43 44 4e 3a 20 49 6d 70 65 |net..X-CDN: Impe|
 |000003e0| 72 76 61 0d 0a 43 6f 6e 74 65 6e 74 2d 45 6e 63 |rva..Content-Enc|
 |000003f0| 6f 64 69 6e 67 3a 20 67 7a 69 70 0d 0a 54 72 61 |oding: gzip..Tra|
 |00000400| 6e 73 66 65 72 2d 45 6e 63 6f 64 69 6e 67 3a 20 |nsfer-Encoding: |
 |00000410| 63 68 75 6e 6b 65 64 0d 0a 58 2d 49 69 6e 66 6f |chunked..X-Iinfo|
 |00000420| 3a 20 31 32 2d 36 37 33 36 30 35 39 32 2d 36 37 |: 12-67360592-67|
 |00000430| 31 30 36 33 38 30 20 70 4e 59 4e 20 52 54 28 31 |106380 pNYN RT(1|
 |00000440| 36 32 35 32 33 38 39 30 36 39 36 35 20 32 39 35 |625238906965 295|
 |00000450| 29 20 71 28 30 20 30 20 30 20 2d 31 29 20 72 28 |) q(0 0 0 -1) r(|
 |00000460| 31 20 31 29 20 55 35 0d 0a 0d 0a                |1 1) U5....     |
 +--------+-------------------------------------------------+----------------+
 [piloting] [reactor-http-nio-4] [DEBUG] 2021-07-02 17:15:06.997 org.springframework.core.log.LogFormatUtils: [6215dde9] [e80c6acf-1] Response 204 NO_CONTENT

解决方法

if(status.equals(NO_CONTENT)){
   Mono.just(emptyList());
}
return clientResponse.bodyToMono(DateKpi.class);

对于上面的代码片段,当状态代码为 204(无内容)时,将始终调用 bodyToMono。在这种情况下,bodyToMono 将发出一个空的 Mono (Mono.empty)。

如果期望的结果是返回一个带有空列表作为值的 Mono,那么代码应该类似于

if(status.equals(NO_CONTENT)){
   return Mono.just(emptyList());
}
return clientResponse.bodyToMono(DateKpi.class);