如何将响应解码为列表?
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 没有看到可以反序列化到的列表。只有 有 列表的东西。这是一个关键的区别。
您有多种选择。
您已按照 Marco 的建议将您的 ClassToDecode 转换为列表。 (还有 AbstractList 如果你真的想变得很花哨,我认为 Marco 的建议更好,因为你不必为一次性 class 添加任何逻辑。)我认为这是一个很好的建议,如果你需要反序列化到特定的 class.
您可以只使用 List 而不是 ClassToDecode。如果你在 class 中没有什么特别的,这就足够了。但它可能不是。如果需要,您当然也可以稍后 new ClassToDecode(deserializedJsonList)
。如果您只需要一个用于反序列化的对象,这可能是您最好的选择。
如果您控制 JSON 发送出去,您可以将列表放在一个称为响应的字段中,正如 Marco 指出的那样。这样你的对象映射器应该能够处理事情。
您可以使用自定义反序列化器来反序列化列表。不过也就是我们说的,大炮打麻雀。
以上回答正确。但是,我用这种方式解决了这个问题:
protected List<ClassToDecode> createResponse(HttpResponse<HttpBodyCodec> response) {
return response.body().decodeAs(new TypeRef<>() { });
}
只是另一种解决方法。
我收到了这个回复:
[{"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 没有看到可以反序列化到的列表。只有 有 列表的东西。这是一个关键的区别。
您有多种选择。
您已按照 Marco 的建议将您的 ClassToDecode 转换为列表。 (还有 AbstractList 如果你真的想变得很花哨,我认为 Marco 的建议更好,因为你不必为一次性 class 添加任何逻辑。)我认为这是一个很好的建议,如果你需要反序列化到特定的 class.
您可以只使用 List 而不是 ClassToDecode。如果你在 class 中没有什么特别的,这就足够了。但它可能不是。如果需要,您当然也可以稍后
new ClassToDecode(deserializedJsonList)
。如果您只需要一个用于反序列化的对象,这可能是您最好的选择。如果您控制 JSON 发送出去,您可以将列表放在一个称为响应的字段中,正如 Marco 指出的那样。这样你的对象映射器应该能够处理事情。
您可以使用自定义反序列化器来反序列化列表。不过也就是我们说的,大炮打麻雀。
以上回答正确。但是,我用这种方式解决了这个问题:
protected List<ClassToDecode> createResponse(HttpResponse<HttpBodyCodec> response) {
return response.body().decodeAs(new TypeRef<>() { });
}
只是另一种解决方法。