2015-09-28 6 views
0

У меня есть базовый веб-сервер java для сохранения истории платежей пользователей. Я пытаюсь написать метод для возврата списка платежей путем запроса базы данных, но по какой-то причине клиент продолжает бросать исключение.Джерси сервер JSON ответ бросает MalformedChunkCodingException: Chunked поток закончился неожиданно

Вот мой метод ресурсов для сервера:

@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

Поэтому список определенно заполнен тремя платежами, которые пользователь сделал ранее. Я добавил список к корневой 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 вызывает ошибки, у меня есть ответы из того же ресурса отправляется обратно без ошибок. это происходит только тогда, когда я пытаюсь отправить заполненный список. Если список пуст ответ от сервера

{ "платежи": []}


Update

Я использовал следующий код, предлагаемых в ответы:

return Response.ok().entity(response.toArray()).build(); 

Аннотации классов a re следующим образом:

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

ответ

1

Я понял, что Объект, который я возвращал, Платеж, содержал связанный объект 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

Это исключение всякий раз, когда возникает проблема в заголовке с запросом HTTP. Если бы я должен был догадаться, ваша конкретная проблема может быть вызвана тем фактом, что вы отправляете список, поэтому заголовок не заканчивается должным образом. Попробуйте вызвать метод toArray() в списке, чтобы преобразовать его в массив перед его отправкой.

+0

спасибо за ваше предложение Aurasphere. Я попытался отправить массив в качестве альтернативы, с той же проблемой. Я также отправил списки из других мест в код сервера, который обрабатывается в одном и том же клиентском коде. Я обновлю еще несколько образцов –

Смежные вопросы