OkHttp Response 在客户端没有提供 body 对象

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

我正在 Spring Boot 中使用 okhttp 库编写 REST API。我的 OkHttpClient 从另一个 API(服务器)请求 GET 请求(客户端)。客户端和服务器都使用 OkHtttp 库,因此我使用 okhttp.response 从服务器返回一个对象。在服务器端,我能够正确打印响应对象内的正文,而在客户端,我在客户端的响应对象中看不到预期的对象。dd

客户端:

OkHttpClient httpClient = new OkHttpClient();
Request request = new Request.Builder()
        .url("http://localhost:8081/temp/getResponse2")
        .build();
Response response = httpClient.newCall(request).execute();
final String body = response.body().string();
response.body().close();
System.out.println("The response is: " + response.toString());
System.out.println("The body in response is: " + body);
return body;

服务器端(API):

@GetMapping(path = "/temp/getResponse2")
    public Response testGETAWBNotes2() throws IOException {
        final ABNotes abNotes = ABNotes.builder()
                .name("name")
                .remarks("remarks")
                .build();
//        return new ResponseEntity<>(awbNotes, HttpStatus.OK);
        Request request = new Request.Builder()
                .url("https://www.google.com")
                .build();
        okhttp3.ResponseBody responseBody = okhttp3.ResponseBody.create(objectMapper.writeValueAsString(abNotes),
                MediaType.parse("application/json; charset=utf-8"));
        Response response = new Response.Builder()
                .request(request)
                .body(responseBody)
                .protocol(Protocol.HTTP_1_1)
                .message("Success")
                .code(200)
                .build();
        System.out.println("the body is: " + response.body().string());
        response.body().close();
        return response;
    }

在服务器端,主体有对象:
“正文是:{“名称”:“名称”,“备注”:“备注”}”
在客户端,我将主体对象视为:
“响应正文为:{“lazyCacheControl$okhttp”:null,“redirect”:false,“successful”:true}”

但是当我使用 RepsonseEntity 从服务器端返回 ABNotes 对象时,我能够在客户端看到 ABNotes 对象,但当我从服务器端返回 ohttp.Response 时,情况并非如此。

另一个问题是:我们必须在响应正文中放入什么请求对象?如果我们的 API 不接受来自客户端的任何输入,在这种情况下我们应该在响应中放入什么请求,是否放置一个虚拟请求对象有效吗?

我找不到任何有用的服务器端响应构建示例与客户端代码示例配对。关于我在这里犯错的地方有什么想法或建议吗?

提前致谢。

在服务器代码中,您手动构造一个 OkHttp Response 对象并从 Spring 控制器返回它。这不是 Spring Boot 的典型用例,因为 Spring 希望您返回域对象或

ResponseEntity<?>
对象,然后将其序列化为 JSON(或其他格式,取决于配置)并将其包装在 HTTP 响应中。

当您手动创建并返回 OkhHttp Response 时,Spring Boot 不会将响应正文序列化为 JSON,而是将 Response 对象本身视为响应正文。这就是为什么您在客户端看到的是 Response 对象本身的内部字段 (

"lazyCacheControl$okhttp": null,"redirect": false,"successful": true
) 的 JSON 表示,而不是预期的 JSON 数据。

要解决此问题并与典型的 Spring Boot 实践保持一致,您应该直接从服务器端点返回域对象或 ResponseEntity:

@GetMapping(path = "/temp/getResponse2")
public ResponseEntity<ABNotes> testGETAWBNotes2() throws IOException {
    ABNotes abNotes = ABNotes.builder()
        .name("name")
        .remarks("remarks")
        .build();
    return new ResponseEntity<>(abNotes, HttpStatus.OK);
}

在您的客户端代码中,我建议添加一个 try-with-resources 块,以确保响应正文在使用完毕后关闭。这是避免资源泄漏的最佳实践。

try (Response response = httpClient.newCall(request).execute()) {
    final String body = response.body().string();
    System.out.println("The body in response is: " + body);
    return body;
} catch (IOException e) {
    // Handle the error appropriately
}

java spring-boot rest okhttp
1个回答
0
投票

在服务器代码中,您手动构造一个 OkHttp Response 对象并从 Spring 控制器返回它。这不是 Spring Boot 的典型用例,因为 Spring 希望您返回域对象或

ResponseEntity<?>
对象,然后将其序列化为 JSON(或其他格式,取决于配置)并将其包装在 HTTP 响应中。

当您手动创建并返回 OkhHttp Response 时,Spring Boot 不会将响应正文序列化为 JSON,而是将 Response 对象本身视为响应正文。这就是为什么您在客户端看到的是 Response 对象本身的内部字段 (

"lazyCacheControl$okhttp": null,"redirect": false,"successful": true
) 的 JSON 表示,而不是预期的 JSON 数据。

要解决此问题并与典型的 Spring Boot 实践保持一致,您应该直接从服务器端点返回域对象或 ResponseEntity:

@GetMapping(path = "/temp/getResponse2")
public ResponseEntity<ABNotes> testGETAWBNotes2() throws IOException {
    ABNotes abNotes = ABNotes.builder()
        .name("name")
        .remarks("remarks")
        .build();
    return new ResponseEntity<>(abNotes, HttpStatus.OK);
}

在您的客户端代码中,我建议添加一个 try-with-resources 块,以确保响应正文在使用完毕后关闭。这是避免资源泄漏的最佳实践。

try (Response response = httpClient.newCall(request).execute()) {
    final String body = response.body().string();
    System.out.println("The body in response is: " + body);
    return body;
} catch (IOException e) {
    // Handle the error appropriately
}
© www.soinside.com 2019 - 2024. All rights reserved.