java - Micronaut HTTP 客户端 - 反序列化泛型类型 - 用于 API 测试
问题描述
对于 API 测试,我必须使用 io.micronaut.http.client.HttpClient 解析请求的响应
我更喜欢使用下面给出的格式。
Response<User> response =
client.toBlocking().retrieve(HttpRequest.POST("/", user), Response.class);
但它不起作用。尝试从响应中获取用户时出现类型转换错误
User user = response.getUser();
目前我正在使用ObjectMapper (Jackson),如下所示,
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检索方法?或以任何其他方式将泛型类类型与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:类 java.util.LinkedHashMap 无法转换为类 my.app.domain.User(java.util.LinkedHashMap 位于加载器“bootstrap”的模块 java.base 中;my.app.domain.User。用户位于加载程序“app”的未命名模块中)