gpt4 book ai didi

java - RestTemplate postForEntity 遇到 java.io.IOException : Premature EOF error

转载 作者:行者123 更新时间:2023-12-01 19:32:36 77 4
gpt4 key购买 nike

对于我的一个 Maven 项目中的问题,我们将不胜感激。

Exception in thread "main" org.springframework.web.client.ResourceAccessException: I/O error on POST request for "https://test-services.domain.ph/campaign/": Premature EOF; nested exception is java.io.IOException: Premature EOF
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:666)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:613)
at org.springframework.web.client.RestTemplate.postForEntity(RestTemplate.java:407)
at homecredit.ph.CampaignConnector.call(CampaignConnector.java:46)
Caused by: java.io.IOException: Premature EOF
at sun.net.www.http.ChunkedInputStream.readAheadBlocking(ChunkedInputStream.java:565)
at sun.net.www.http.ChunkedInputStream.readAhead(ChunkedInputStream.java:609)
at sun.net.www.http.ChunkedInputStream.read(ChunkedInputStream.java:696)
at java.io.FilterInputStream.read(FilterInputStream.java:133)

来源:

ResponseEntity<ApiResponse> response = restTemplate.postForEntity(url, entity, ApiResponse.class);

目的地:

@RequestMapping(value="/campaign", method = RequestMethod.POST, consumes=MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<ApiResponse> insertCampaignRecord(
@Valid @RequestBody CampaignRecordInsertRequest campaignRecordInsertRequest){
logInfo("Incoming insert request. " + DescriptorUtility.convertToString(campaignRecordInsertRequest));
campaignDataService.insertNewRecord(CampaignRecordConverter.convertToCampaignRecord(campaignRecordInsertRequest));
return ResponseUtility.defaultResponse();
}

响应实用程序

public static ResponseEntity<ApiResponse> defaultResponse(){
ApiResponse apiResponse = new ApiResponse();
apiResponse.setTimestamp(DateUtility.currentDateString());
apiResponse.setMessage(ResponseMessages.SUCCESS);
return new ResponseEntity<>(apiResponse, HttpStatus.OK);
}

Activity 数据服务

@Async("AsyncExecutor")
public void insertNewRecord(CampaignRecord campaignRecord) {
try {
campaignRecordRepository.save(campaignRecord);
} catch (Exception e) {
logError(e);
}
}

服务器日志

2017-09-11 11:11:11  INFO 18383 [http-nio-8773-exec-10] [CampaignRecordController] - Incoming insert request. {"dateCampaign":1504656000000,"cuid":...
2017-09-11 11:11:11 WARN 18383 [http-nio-8773-exec-10] [SqlExceptionHelper] - SQL Error: 1062, SQLState: 23000
2017-09-11 11:11:11 ERROR 18383 [http-nio-8773-exec-10] [SqlExceptionHelper] - Duplicate entry 'CMP_CLX##1208637#20170906' for key 'UNIQUE_KEY'
2017-09-11 11:11:11 ERROR 18383 [http-nio-8773-exec-10] [CampaignDataService] - could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
2017-09-11 11:11:11 ERROR 18383 [http-nio-8773-exec-10] [CampaignDataService] - could not execute statement
PS。服务器日志正常(记录保存成功与否返回成功响应)

问题是间歇性的。发送批量请求时随机发生。

提前致谢! :)

最佳答案

我在 Spring Boot 2.1 中遇到了同样的问题。就我而言,我有 3 个应用程序(称它们为 A、B 和 C),其中 B 实际上只是 A 和 C 之间的代理:

A --> B --> C

从 B A 的响应中发生了过早 EOF。所有指示都是成功的 HTTP 响应 (200),但检查使用调试器的响应正文显示它在序列化 DTO 数据的中间有一个换行符,而不是在我预期的末尾:

enter image description here

(注意id字段后面的返回字符,并且缺少任何内容长度;忽略末尾的不可读框,它们是未初始化/使用的字节数组的一部分)

就我而言,服务 B 既是服务器又是客户端。代码看起来像这样:

public ResponseEntity<String> handle(String request, HttpHeaders headers) {

// Do some validation and then call Service C, and pass the response
// back to Service A

return restTemplate.postForEntity(
urlForServiceC,
new HttpEntity<>(request, headers),
String.class);
}

我没有深入研究 RestTemplate 或其消息转换器的内部,但让我意识到响应缓冲可能存在问题的是我使用了 Spring filter记录每个服务的响应。此过滤器必须复制响应流,以避免与已使用的正文相关的其他过滤器出现异常。

我注意到,当我启用此过滤器运行时,Premature EOF 异常消失了。当我禁用它时,异常又回来了。有关复制响应流的一些操作已经解决了 Premature EOF 错误。

这促使我在服务 B 中尝试以下操作:

public ResponseEntity<String> handle(String request, HttpHeaders headers) {

// Do some validation and then call Service C, and pass the response
// back to Service A

String response = restTemplate.postForEntity(
urlForServiceC,
new HttpEntity<>(request, headers),
String.class).getBody();

return ResponseEntity.ok(response);
}

微妙的变化是我首先将响应保存到本地变量,这需要我调用ResponseEntity.getBody()。这会强制在返回服务 A 之前消耗来自服务 C 的整个响应正文。进行此更改后,我的 Premature EOF 错误尚未返回。

关于java - RestTemplate postForEntity 遇到 java.io.IOException : Premature EOF error,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46147813/

77 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com