2014-02-20 5 views
9

Моя цель - сделать веб-звонки и конвертировать возвращенный JSON в POJO. Я пытаюсь использовать Джерси + Джексон для этого, но я получаю исключения при запуске.Jersey 2.6 with Jackson JSON deserialization

Моего файл Maven П включает в себя следующую зависимость -

<dependency> 
    <groupId>org.glassfish.jersey.core</groupId> 
    <artifactId>jersey-client</artifactId> 
    <version>2.6</version> 
</dependency> 
<dependency> 
    <groupId>org.glassfish.jersey.media</groupId> 
    <artifactId>jersey-media-json-jackson</artifactId> 
    <version>2.6</version> 
</dependency> 

Код, я использую, чтобы принести некоторые данные следующим образом -

Client client = ClientBuilder.newBuilder() 
      .register(JacksonFeature.class) 
      .build(); 
ClientResponse response = client.target(url).request(MediaType.APPLICATION_JSON).get(ClientResponse.class); 

Но следующее исключение бросок -

javax.ws.rs.ProcessingException: Error reading entity from input stream. 
at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:868) 
at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:785) 
at org.glassfish.jersey.client.ClientResponse.readEntity(ClientResponse.java:335) 
... 
... 
Caused by: org.codehaus.jackson.map.JsonMappingException: Can not find a deserializer for non-concrete Map type [map type; class javax.ws.rs.core.MultivaluedMap, [simple type, class java.lang.String] -> [collection type; class java.util.List, contains [simple type, class java.lang.String]]] 
at org.codehaus.jackson.map.deser.StdDeserializerProvider._createAndCache2(StdDeserializerProvider.java:315) 
at org.codehaus.jackson.map.deser.StdDeserializerProvider._createAndCacheValueDeserializer(StdDeserializerProvider.java:290) 
at org.codehaus.jackson.map.deser.StdDeserializerProvider.findValueDeserializer(StdDeserializerProvider.java:159) 
at org.codehaus.jackson.map.deser.std.StdDeserializer.findDeserializer(StdDeserializer.java:620) 
at org.codehaus.jackson.map.deser.BeanDeserializer.resolve(BeanDeserializer.java:379) 
at org.codehaus.jackson.map.deser.StdDeserializerProvider._resolveDeserializer(StdDeserializerProvider.java:407) 
at org.codehaus.jackson.map.deser.StdDeserializerProvider._createAndCache2(StdDeserializerProvider.java:352) 
at org.codehaus.jackson.map.deser.StdDeserializerProvider._createAndCacheValueDeserializer(StdDeserializerProvider.java:290) 
at org.codehaus.jackson.map.deser.StdDeserializerProvider.findValueDeserializer(StdDeserializerProvider.java:159) 
at org.codehaus.jackson.map.deser.StdDeserializerProvider.findTypedValueDeserializer(StdDeserializerProvider.java:180) 
at org.codehaus.jackson.map.ObjectMapper._findRootDeserializer(ObjectMapper.java:2829) 
at org.codehaus.jackson.map.ObjectMapper._readValue(ObjectMapper.java:2699) 
at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1315) 
at org.codehaus.jackson.jaxrs.JacksonJsonProvider.readFrom(JacksonJsonProvider.java:419) 
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.invokeReadFrom(ReaderInterceptorExecutor.java:257) 
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:229) 
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:149) 
at org.glassfish.jersey.message.internal.MessageBodyFactory.readFrom(MessageBodyFactory.java:1124) 
at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:853) 
... 90 more 
Caused by: java.lang.IllegalArgumentException: Can not find a deserializer for non-concrete Map type [map type; class javax.ws.rs.core.MultivaluedMap, [simple type, class java.lang.String] -> [collection type; class java.util.List, contains [simple type, class java.lang.String]]] 
at org.codehaus.jackson.map.deser.BasicDeserializerFactory.createMapDeserializer(BasicDeserializerFactory.java:424) 
at org.codehaus.jackson.map.deser.StdDeserializerProvider._createDeserializer(StdDeserializerProvider.java:380) 
at org.codehaus.jackson.map.deser.StdDeserializerProvider._createAndCache2(StdDeserializerProvider.java:310) 
... 108 more 

Я пропустил некоторые настройки, чтобы заставить это работать правильно? Я пробовал URL через curl и браузер, и он возвращает JSON, как ожидалось.

ответ

23

Что вам нужно, это ответ и не ClientResponse:

javax.ws.rs.core.Response jsonResponse = client.target(url).request(MediaType.APPLICATION_JSON).get(); 

Тогда вы можете увидеть, что происходит в вашем ответе (отладка ваш друг здесь). Может быть, это карта какого-то типа? Если это так, вы можете прочитать его, выполнив, например,

Map<SomeClassOfYours> entitiesFromResponse = jsonResponse.readEntity(new GenericType<Map<SomeClassOfYours>>() {}); 

Если вы клали нормальный объект в ответ вы можете просто сделать что-то вроде:

SomeClassOfYours entityFromResponse = jsonResponse.readEntity(SomeClassOfYours.class); 

Edit: Для этой работы вы также должны определить SomeClassOfYours и поставить соответствующий поля, конструктор, геттеры и сеттеры.

Edit2: Если вы сомневаетесь, вы всегда можете прочитать jsonResponse как String.class и поместить его в переменную String.

+0

Я попробовал это изначально, но по какой-то причине моя IDE не находит readEntity в объекте Response (jsonResponse). – ashutosh

+0

Можете ли вы также объяснить, почему я должен использовать Response? И когда я буду использовать ClientResponse? – ashutosh

+1

ClientResponse - это реликвия из майки 1.x. См. Https://jersey.java.net/documentation/latest/user-guide.html#mig-1.x. Какую ошибку вы получаете, когда пытаетесь использовать Response.readEntity()? – ingenious

-1
Response jsonResponse = getClient().target(URI).request().get(); 
T result = jsonResponse.readEntity(type); 
+7

Ответы всегда сильнее, если вы также немного объясните свое решение. – Magnilex

+0

@Magnilex идея состояла в том, чтобы использовать общий тип, завернутый в javax.ws.rs.core.Response, чтобы обмениваться типизированными экземплярами назад и вперед между бэкэндом и компонентами приложения. – Oleksii

+1

Отлично. :) Если бы я был вами, я бы отредактировал вопрос и добавлю к нему объяснение. – Magnilex

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