2015-09-28 92 views
0

我有一個基本的Java Web服務器用於持久化用戶的付款歷史記錄。 我想寫一個方法來通過查詢數據庫返回支付列表,但由於某種原因客戶端不斷拋出異常。澤西服務器JSON響應拋出MalformedChunkCodingException:分塊流意外結束

這裏是我的服務器資源的方法:

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

班級註釋a如下:

@Produces({MediaType.APPLICATION_JSON}) 
@Consumes({MediaType.APPLICATION_JSON}) 

與拋出異常相同。爲了清楚起見,我之前在服務器的另一部分中使用了這種類型的響應。來自此的響應也是一個JSON列表,並由相同的客戶端代碼處理。

這裏是一個工作的另一種方法:每當有與HTTP請求報頭中的問題

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

回答

1

我意識到我返回的對象Payment包含一個鏈接的JPA對象。所以我的回答包含了整個數據庫對象和所有關係。 當我試圖提取字符串時,客戶端仍在接收數據,因此引發異常。 我用不同的方法來提取HttpEntity字符串,那就是:

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

這讓我看到了完整的字符串。

而且重複這個問題:使用的一些代碼有 link to stackoverflow question

1

拋出此異常。如果我不得不猜測,你的具體問題可能是由於你正在發送一個列表,所以標題不能正常結束。嘗試調用列表的toArray()方法,在發送之前將其轉換爲數組。

+0

感謝您的建議Aurasphere。我曾嘗試發送一個數組作爲替代方案,具有相同的問題。我還從服務器代碼中的其他地方發送了列表,這些代碼在相同的客戶端代碼中處理得很好。我會更新一些樣品 –