Micronaut HTTP客户端 - 反序列化通用类型 - 用于API测试。

问题描述 投票:0回答:1

为了测试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"
}
java junit jackson micronaut micronaut-client
1个回答
1
投票

你有几个选项。

如果你只需要 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')

© www.soinside.com 2019 - 2024. All rights reserved.