2017-09-11 115 views
2

希望對我的某個Maven項目有任何幫助。遇到java.io.IOException的RestTemplate postForEntity:提前發生EOF錯誤

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(); 
} 

ResponseUtility

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

CampaignData服務

@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。服務器日誌正常(返回成功響應,或者記錄成功保存或不成功)

問題是間歇性的。發送批量請求時隨機發生。

在此先感謝! :)

+0

這些是客戶端日誌,您在服務器日誌中看到的任何跟蹤? –

+0

更新了有關日誌的問題描述。 但是服務器是異步設計的,所以要麼失敗了,它必須返回一個成功的響應。 –

+0

也分享campaignDataService.insertNewRecord代碼。 –

回答

0

基於服務器日誌好像,服務器正在嘗試保存一些記錄和其失敗(由於唯一鍵衝突)。

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 

貌似服務器無法處理正常的異常,整個流程中斷,導致HTTP-500響應代碼(可能)空響應。

兩個動作,你可以採取:

  1. 處理異常優雅。
  2. 驗證唯一密鑰被違反的原因,並在可能的情況下進行修復。
+0

嗨,如我的控制器上所示,不管數據插入後的結果如何,我返回一個固定響應,所以我不認爲這是問題:) –

+0

代碼包裝在try-catch下,所以異常不會傳播。下一步是以String格式記錄響應,不要試圖在ApiResponse下單步完成,這將幫助您確定您從服務器接收到的內容。此外,爲什麼您將服務方法設置爲@Async,如果您使用的是Servlet 3.1,則使用異步控制器(例如,Callable或DeferredResult) –

+0

Upvote使我意識到與ResponseEntity進行覈對。 雖然問題似乎是無關的,無論如何,謝謝! 我不好早一點指出來。 –

0

對於任何可能遇到此問題的人。 問題是由春季啓動尤里卡造成的。 似乎在大規模傳遞ResponseEntity響應(批量處理)時會導致響應狀態格式錯誤。

當前的解決方法是從ResponseEntity切換到對象正文。