为了测试API,我必须使用io.micronaut.http.client.HttpClient来解析一个请求的响应。
我喜欢使用下面的格式。
Response<User> response =
client.toBlocking().retrieve(HttpRequest.POST("/", user), Response.class);
但它不工作。当我试图从响应中获取用户时,我得到了类型转换错误。
User user = response.getUser();
目前我使用的是 ObjectMapper (杰克逊)就像下面给出的。
String response = client.toBlocking().retrieve(HttpRequest.POST("/", user), String.class);
ObjectMapper objectMapper = new ObjectMapper();
Response<User> response = objectMapper.readValue(response, new TypeReference<Response<User>>() {});
有什么办法可以使用 TypeReference 直接与 HttpClient retrieve方法?或其他任何方法来使用通用类类型与 HttpClient.
其他有用信息
// Response generic class
class Response<T> {
T data;
....
}
答复样本
{
"data": {
"name":"sample"
},
"message": "Success"
}
你有几个选项。
如果你只需要 User
对象实例,你可以通过 retrieve()
方法,其中第二个参数是域类(User
在您的情况下),然后您可以使用 user
变量。
User user = client.toBlocking().retrieve(HttpRequest.POST("/", user), User.class);
assertThat(user)
.isNotNull()
.extracting(User::getName)
.isEqualTo("sample");
如果你也需要响应对象(例如能够检查响应代码),那么你应该使用 exchange()
方法,然后得到 User
实例通过调用 body()
方法。
HttpResponse<User> response = client.toBlocking()
.exchange(HttpRequest.POST("/", user), User.class);
assertThat(response)
.isNotNull()
.extracting(HttpResponse::body)
.extracting(User::getName)
.isEqualTo("sample");
更新: 当你需要使用通用类作为响应时,你必须使用 Argument.of()
的第二个参数,作为 retrieve()
和 exchange()
方法,你可以指定响应的通用类和它的类型参数。请看这个例子。
Response<User> response = client.toBlocking()
.retrieve(HttpRequest.POST("/", user), Argument.of(Response.class, User.class));
assertThat(response)
.isNotNull()
.extracting(Response::getData)
.extracting(User::getName)
.isEqualTo("sample");
如果你不使用 Argument.of()
那么它将转换 data
属性为 LinkedHashMap
而不是 User
还有这个
Response<User> response = client.toBlocking().retrieve(HttpRequest.POST("/", user), Response.class);
response.getData().getName();
...会扔 ClassCastException
:
java.lang.ClassCastException: class java.util.LinkedHashMap cannot be cast to class my.app.domain.User (java.util.LinkedHashMap is in module java.base of loader 'bootstrap'; my.app.domain.User.User is in unnamed module of loader 'app')