我正在 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
在服务器代码中,您手动构造一个 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
}