Джерси 2.6 с десериализацией Jackson JSON

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

Мой файл maven pom включает следующие зависимости:

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

Но следующее исключение - это throw -

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, как и ожидалось.


person ashutosh    schedule 20.02.2014    source источник


Ответы (2)


Вам нужен ответ, а не ответ клиента:

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

Изменить: чтобы это работало, вам также необходимо определить SomeClassOfYours и поместить туда соответствующие поля, конструктор, геттеры и сеттеры.

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

person ingenious    schedule 20.02.2014
comment
Я пробовал это изначально, но по какой-то причине моя IDE не находит readEntity в объекте Response (jsonResponse). - person ashutosh; 21.02.2014
comment
Не могли бы вы также объяснить, почему я должен использовать Response? И когда мне следует использовать ClientResponse? - person ashutosh; 21.02.2014
comment
ClientResponse — это пережиток трикотажа 1.x. См. jersey.java.net/documentation/latest/user. -guide.html#mig-1.x . Какую ошибку вы получаете, когда пытаетесь использовать Response.readEntity()? - person ingenious; 21.02.2014
comment
Netbeans показал исключение, в котором говорилось, что метод readEntity не существует. Но просмотр исходного кода ясно показал метод. Код скомпилировался, но во время выполнения выдал ошибку о том, что метод не существует. Позже я обновил свой java-ee-web-api с версии 6 до 7, и теперь readEntity работает нормально. Спасибо. - person ashutosh; 22.02.2014
comment
client.target(url).request(MediaType.APPLICATION_JSON).get(YourClass.class) может быть более интуитивным? - person macemers; 02.07.2015

person    schedule
comment
Ответы всегда будут сильнее, если вы также немного объясните свое решение. - person Magnilex; 22.02.2015
comment
@Magnilex Идея заключалась в том, чтобы использовать общий тип, завернутый в javax.ws.rs.core.Response, для обмена типизированными экземплярами между внутренней и внешней частями приложения. - person Oleksii Kyslytsyn; 23.02.2015
comment
Большой. :) На вашем месте я бы отредактировал вопрос и добавил к нему объяснение. - person Magnilex; 23.02.2015