如何将响应解码为列表?

How can I decode a response as a list?

我收到了这个回复:

[{"id":1,"someField":"someValue"}]

这是我的要求:

private HttpRequest doRequest(String body, URI uri) {
    return HttpRequest.newBuilder()
            .POST(HttpRequest.BodyPublishers.ofString(body))
            .uri(uri)
            .headers(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON)
            .build();
}

我尝试这样做,但是没有成功:

protected ClassToDecode createResponse(HttpResponse<HttpBodyCodec> response) {
    return response.body().decodeAs(ClassOfResponse.class);
}

我的 ClassToDecode 有我的回复列表 class:

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString
@Builder
@EqualsAndHashCode
public class ClassToDecode {
    private List<ClassResponse> responses;
}

和我的 ClassResponse 以及要解码的字段:

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString
@Builder
@EqualsAndHashCode
public class ClassResponse  {

  @JsonProperty("id")
  private Integer id = null;

  @JsonProperty("someField")
  private String someField = null;

}

这样做,字段不会填充响应。 我无法解码收到的列表,我该怎么办?

您的 class ClassToDecode 不起作用的原因是因为它试图在 json 对象中找到键 responses,如下所示:

{"responses":[{"id":1,"someField":"someValue"}]}

做你想做的最简单的方法是:

public class ClassToDecode extends ArrayList<ClassResponse> {
}

这应该是我们的工作,帮你解码。

问候。

您尝试做的事情实际上并没有按原样工作,因为:

  • Jackson 看到 JSON 类型是 list/array 事物。
  • Jackson 没有看到可以反序列化到的列表。只有 列表的东西。这是一个关键的区别。

您有多种选择。

  1. 您已按照 Marco 的建议将您的 ClassToDecode 转换为列表。 (还有 AbstractList 如果你真的想变得很花哨,我认为 Marco 的建议更好,因为你不必为一次性 class 添加任何逻辑。)我认为这是一个很好的建议,如果你需要反序列化到特定的 class.

  2. 您可以只使用 List 而不是 ClassToDecode。如果你在 class 中没有什么特别的,这就足够了。但它可能不是。如果需要,您当然也可以稍后 new ClassToDecode(deserializedJsonList)。如果您只需要一个用于反序列化的对象,这可能是您最好的选择。

  3. 如果您控制 JSON 发送出去,您可以将列表放在一个称为响应的字段中,正如 Marco 指出的那样。这样你的对象映射器应该能够处理事情。

  4. 您可以使用自定义反序列化器来反序列化列表。不过也就是我们说的,大炮打麻雀。

以上回答正确。但是,我用这种方式解决了这个问题:

protected List<ClassToDecode> createResponse(HttpResponse<HttpBodyCodec> response) {
    return response.body().decodeAs(new TypeRef<>() { });
}

只是另一种解决方法。