簡體   English   中英

澤西服務器JSON響應引發MalformedChunkCodingException:分塊的流意外結束

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM