web-dev-qa-db-ja.com

Jackson JSON逆シリアル化を使用したJersey 2.6

私の目標は、Web呼び出しを行い、返されたJSONをPOJOに変換することです。これにJersey + Jacksonを使用しようとしていますが、実行中に例外が発生します。

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

しかし、次の例外がスローされます-

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

これを正しく機能させるための設定が不足していますか? curlとブラウザを介してURLを試しましたが、期待どおりにJSONを返します。

12
ashutosh

必要なのはレスポンスであり、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);

編集:これを機能させるには、SomeClassOfYoursを定義し、対応するフィールド、コンストラクター、ゲッター、セッターをそこに配置する必要もあります。

Edit2:疑問がある場合は、jsonResponseを常にString.classとして読み取り、String変数に入れることができます。

26
ingenious