![](/img/trans.png)
[英]MalformedChunkCodingException: Chunked stream ended unexpectedly
[英]Jersey server JSON response throwing MalformedChunkCodingException: Chunked stream ended unexpectedly
我有一個用於保留用戶付款歷史記錄的基本Java Web服務器。 我正在嘗試編寫一種通過查詢數據庫來返回付款清單的方法,但是由於某些原因,客戶端不斷拋出異常。
這是服務器的資源方法:
@RolesAllowed({"authenticated","administrator","superadministrator"})
@Path("getPaymentHistory/{userId}")
@GET
public Response getPaymentHistory(@Context SecurityContext sc, @PathParam("userId") String userId){
PaymentListResponse response = paymentService.getUserPaymentHistory(userId);
logger.debug("payment service found " +response.getPayments().size()+ " payments for user: " + userId);
return Response.ok().entity(response).build();
}
這將產生以下日志:
DEBUG cbspresource.PaymentResource-付款服務找到了3個用戶付款:c832f8c2-f5ff-4e5c-a1b9-7e5a3f26a359
因此,該列表肯定填充了用戶之前進行的3次付款。 我將列表添加到XML根元素中,因為我認為這可能是導致異常的原因:
@XmlRootElement
public class PaymentListResponse {
private List<Payment> payments = new ArrayList<Payment>();
public PaymentListResponse(){}
//getter & setter ..
}
這是我的客戶代碼:
DefaultHttpClient httpClient = new DefaultHttpClient();
String responseString = null;
HttpResponse response;
try {
response = httpClient.execute(data);
HttpEntity entity = response.getEntity();
responseString = EntityUtils.toString(entity, "UTF-8");
} catch (HttpException | IOException e) {
e.printStackTrace();
}
return responseString;
這將產生以下日志:
org.apache.http.MalformedChunkCodingException: Chunked stream ended unexpectedly at org.apache.http.impl.io.ChunkedInputStream.getChunkSize(ChunkedInputStream.java:222) at org.apache.http.impl.io.ChunkedInputStream.nextChunk(ChunkedInputStream.java:183) at org.apache.http.impl.io.ChunkedInputStream.read(ChunkedInputStream.java:155) at org.apache.http.conn.EofSensorInputStream.read(EofSensorInputStream.java:159) at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284) at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326) at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178) at java.io.InputStreamReader.read(InputStreamReader.java:184) at java.io.Reader.read(Reader.java:140) at org.apache.http.util.EntityUtils.toString(EntityUtils.java:135)
我無法弄清楚為什么JSON會導致錯誤,我收到了來自同一資源的響應,沒有錯誤地被發回。 僅當我嘗試發送填充列表時,才會發生這種情況。 如果列表為空,則服務器的響應為
{“付款”:[]}
更新資料
我按照答案中的建議使用了以下代碼:
return Response.ok().entity(response.toArray()).build();
類注釋如下:
@Produces({MediaType.APPLICATION_JSON})
@Consumes({MediaType.APPLICATION_JSON})
拋出相同的異常。 為了清楚起見,我之前在服務器的另一部分中使用了這種類型的響應。 該響應也是一個JSON列表,並由相同的客戶端代碼處理。
這是另一種有效的方法:
@RolesAllowed({"administrator","superadministrator"})
@Path("get_all")
@GET
public Response getAccounts(@Context SecurityContext sc) {
ExternalUser userMakingRequest = (ExternalUser)sc.getUserPrincipal();
List<Account> accounts = accountService.getAllAccounts(userMakingRequest);
return Response.ok().entity(accounts).build();
}
只要HTTP請求的標頭中有問題,就會引發此異常。 如果我不得不猜測,您的特定問題可能是由於您正在發送列表而導致的,因此標題沒有正確結束。 嘗試在發送列表之前調用列表的toArray()方法將其轉換為數組。
我意識到我要返回的對象Payment包含一個鏈接的JPA對象。 因此,我的響應包含整個DB對象以及所有關系。 當我嘗試提取String時,客戶端仍在接收數據,因此引發了異常。 我使用了另一種方法從HttpEntity提取String,這里是:
public static String sendGetReqForList(HttpGet get){
DefaultHttpClient httpClient = new DefaultHttpClient();
StringBuilder result = new StringBuilder();
HttpResponse response = null;
try {
response = httpClient.execute(get);
} catch (Exception e) {
e.printStackTrace();
}
InputStream input = null;
try {
input = new BufferedInputStream(response.getEntity().getContent());
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
byte data[] = new byte[40000];
int currentByteReadCount = 0;
/** read response from input stream */
try {
while ((currentByteReadCount = input.read(data)) != -1) {
String readData = new String(data, 0, currentByteReadCount);
result.append(readData);
if (readData.indexOf("}~{") >= 0) {
System.out.println("got json obj from data");
}
}
} catch (IOException e) {
e.printStackTrace();
}
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
/** transform response into JSONArray */
return result.toString();
}
這使我可以看到完整的字符串。
也是該問題的重復:使用了那里的一些代碼來鏈接到stackoverflow問題
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.