通量解码异常:意外字符('['(代码 91)):期望双引号开始字段名称

Flux Decoding Exception : Unexpected character ('[' (code 91)): was expecting double-quote to start field name

在将 Flux JSON 解码为 Java 对象时,出现以下异常:

2019-02-25 13:44:39.136 TRACE [{}] 25292 --- [reactor-http-nio-4] o.s.w.r.f.c.ExchangeFunctions            : [762021a9] Response 200 OK, headers={masked}
2019-02-25 13:44:39.195 ERROR [{}] 25292 --- [reactor-http-nio-4] r.M.C.2                                  : | onError(org.springframework.core.codec.DecodingException: JSON decoding error: Unexpected character ('[' (code 91)): was expecting double-quote to start field name; nested exception is com.fasterxml.jackson.core.JsonParseException: Unexpected character ('[' (code 91)): was expecting double-quote to start field name
 at [Source: UNKNOWN; line: 2, column: 3])
2019-02-25 13:44:39.196 ERROR [{}] 25292 --- [reactor-http-nio-4] r.M.C.2                                  : 
org.springframework.core.codec.DecodingException: JSON decoding error: Unexpected character ('[' (code 91)): was expecting double-quote to start field name; nested exception is com.fasterxml.jackson.core.JsonParseException: Unexpected character ('[' (code 91)): was expecting double-quote to start field name
 at [Source: UNKNOWN; line: 2, column: 3]
    at org.springframework.http.codec.json.Jackson2Tokenizer.tokenize(Jackson2Tokenizer.java:104) ~[spring-web-5.1.2.RELEASE.jar:5.1.2.RELEASE]

按如下方式设置映射器编解码器 属性 无法解决问题:

mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);

这里是 JSON 响应:

[
  {
    "id": "111",
    "description": "xyz"
  },
  {
    "id": "222",
    "description": "pqr"
  }
]

下面是 WebClient 实现:

public Mono<List<ItemServiceResponse>> getItems(ItemServiceRequest itemServiceRequest) {
return webClient
        .post()
        .contentType(MediaType.APPLICATION_JSON)
        .header(HttpHeaders.ACCEPT, MediaType.APPLICATION_STREAM_JSON.toString())
        .body(Mono.just(itemServiceRequest), ItemServiceRequest.class)
        .retrieve()
        .bodyToFlux(ItemServiceResponse.class)
        .collectList()
        .log();
}

这是 Java 对象:

@Builder 
@Data 
@AllArgsConstructor 
@NoArgsConstructor 
public class ItemServiceResponse { 
  private String id; 
  private String description; 
}

ObjectMapper 期望从您的 Json 响应映射单个对象作为 ItemServiceResponse 因此异常(映射器期待 quote).

您应该更新 WebClient 调用以映射 ItemServiceResponsearray:

public Mono<List<ItemServiceResponse>> getItems(ItemServiceRequest itemServiceRequest) {
    return webClient
            .post()
            .contentType(MediaType.APPLICATION_JSON)
            .header(HttpHeaders.ACCEPT, MediaType.APPLICATION_STREAM_JSON.toString())
            .body(Mono.just(itemServiceRequest), ItemServiceRequest.class)
            .retrieve()
            .bodyToFlux(ItemServiceResponse[].class) // <-- array of ItemServiceResponse
            .collectList()
            .log();
}

一个可怕的问题!!!我浪费了 4-5 天的时间来弄清楚我的代码有什么问题,并尝试了所有的排列组合,但没有任何效果。

但是伙计们,Postman 是罪魁祸首,没错。

我得到的 JSON 的实际响应结构:

{
  [
    {
      "id": "111",
      "description": "xyz"
    },
    {
      "id": "222",
      "description": "pqr"
    }
  ]
}

而且格式不正确 JSON。但是 Postman 以某种方式进行了自动更正,并给出了问题中提到的 JSON 的正确响应,我没有更多地关注响应,因为状态代码是 200 成功。

幸运的是,我触发了 Curl 命令并找到了根本原因。请不要相信邮递员......更正不需要的东西真是太聪明了。