我在使用HttpClient::send
带有 custom的 Java 11 直接将 JSON 反序列化为自定义对象时遇到问题HttpResponse.BodyHandler
。我在回答这个 SO question时遇到了这个问题。
我正在使用的版本:
- 开放JDK 11
- 杰克逊 2.9.9.3
我创建了一个简单的泛型JsonBodyHandler
类,它实现HttpResponse.BodyHandler
:
public class JsonBodyHandler<W> implements HttpResponse.BodyHandler<W> {
private final Class<W> wClass;
public JsonBodyHandler(Class<W> wClass) {
this.wClass = wClass;
}
@Override
public HttpResponse.BodySubscriber<W> apply(HttpResponse.ResponseInfo responseInfo) {
return asJSON(wClass);
}
}
该asJSON
方法定义为:
public static <W> HttpResponse.BodySubscriber<W> asJSON(Class<W> targetType) {
HttpResponse.BodySubscriber<String> upstream = HttpResponse.BodySubscribers.ofString(StandardCharsets.UTF_8);
return HttpResponse.BodySubscribers.mapping(
upstream,
(String body) -> {
try {
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.readValue(body, targetType);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
});
}
所以它返回一个自定义HttpResponse.BodySubscriber
,它获取正文String
,然后应用从 JSON 到给定的映射targetType
来测试它的代码:
public static void main(String[] args) throws URISyntaxException, IOException, InterruptedException {
HttpRequest request = HttpRequest.newBuilder(new URI("https://jsonplaceholder.typicode.com/todos/1"))
.header("Accept", "application/json")
.build();
Model model = HttpClient.newHttpClient()
.send(request, new JsonBodyHandler<>(Model.class))
.body();
System.out.println(model);
}
和Model
班级:
public class Model {
private String userId;
private String id;
private String title;
private boolean completed;
//getters setters constructors toString
}
输出如预期:
Model{userId='1', id='1', title='delectus aut autem', completed=false}
但是,当我将asJSON
方法更改为 readInputStream
而不是String
first 时:
public static <W> HttpResponse.BodySubscriber<W> asJSON(Class<W> targetType) {
HttpResponse.BodySubscriber<InputStream> upstream = HttpResponse.BodySubscribers.ofInputStream();
return HttpResponse.BodySubscribers.mapping(
upstream,
(InputStream is) -> {
try (InputStream stream = is) {
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.readValue(stream, targetType);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
});
}
它在调用读取值后挂起ObjectMapper
并且它没有继续(我已经检查它是否成功地从端点获得响应,状态代码是 200)但是它只是挂起。有谁知道可能是什么问题?