web-dev-qa-db-ja.com

content-type application / jsonおよびtype class Java.lang.StringのMessageBodyReaderが見つかりません

ジャクソンプロバイダーでRestEasyクライアントを使用していて、上記のエラーが発生する

クライアントサイドコードは:

_ClientRequest request = new ClientRequest(url);
request.accept(MediaType.APPLICATION_JSON);
ClientResponse<String> response = request.get(String.class);

if (response.getStatus() != 200) {
  throw new RuntimeException("Failed : HTTP error code : " + response.getStatus());
}

BufferedReader br =
  new BufferedReader(new InputStreamReader(new ByteArrayInputStream(response.getEntity().getBytes())));
_

response.getEntity()ClientResponseFailure例外をスローし、エラーは

_Unable to find a MessageBodyReader of content-type application/json and type class Java.lang.String
_

私のサーバー側のコードは以下の通りです:

_@GET
@Path("/{itemId}")
@Produces(MediaType.APPLICATION_JSON)
public String item(@PathParam("itemId") String itemId) {
  //custom code

  return gson.toJSON(object);
}
_
20
user1632803

あなたはあなたのmaven pomに次の依存関係を追加しようとすることができます。

   <dependency>
    <groupId>org.jboss.resteasy</groupId>
    <artifactId>resteasy-jackson-provider</artifactId>
    <version>2.3.4.Final</version>
   </dependency>
53
Dog

問題は、実際にはRestEasyがJacksonプロバイダーを見つけられないことです。次のコードで手動で登録する必要がありました。

   ResteasyProviderFactory instance=ResteasyProviderFactory.getInstance();
    RegisterBuiltin.register(instance);
    instance.registerProvider(ResteasyJacksonProvider.class);

これですべてうまくいきます。しかし、Resteasyはプロバイダーをスキャンして自動的に登録することになっているため、このソリューションにはまだ不満があります。

7
user1632803
Client client = ClientBuilder.newBuilder().register(ResteasyJacksonProvider.class).build();
2
Bruno Horta

org.jboss.resteasy.plugins.providers.jackson.ResteasyJacksonProviderという行をMETA-INF/services/javax.ws.rs.ext.Providersファイルに追加するだけで問題が解決します。

このファイルはresteasy-jackson-providers.jarに含まれていますが、同じファイルが別のjar、restasy-jaxrs.jarにも含まれています。これらの両方のjarを使用する実行可能なjarファイルの場合、マージされません。

1
MatteoM

私のコードを機能させるものは、私が追加したものです:

<dependency>
    <groupId>org.jboss.resteasy</groupId>
    <artifactId>resteasy-jackson2-provider</artifactId>
    <version>&{resteasy.version}</version>
</dependency>

これ以外にも理由はわかりませんが、クライアントが作成されたときにRESTEASYがプロバイダーを初期化していないようです。つまり、手動でプロバイダーを初期化する必要がありました。

 ResteasyProviderFactory instance=ResteasyProviderFactory.getInstance();
 RegisterBuiltin.register(instance);
 instance.registerProvider(ResteasyJackson2Provider.class);

一般的には、クライアントを実行するだけで十分です。

1
Dmitry Svn

同様の問題があり、resteasy-jackson-providerのバージョンに関連していることがわかりました。 3.0.4.Finalから3.0.5.Finalに移動したところ、問題は解消しました。

さらに、3行目を次のように変更すると、依存関係を変更する必要がない結果が期待されたものであることがわかりました。

Response response = request.get(Object.class).toString();
0
JCalcines

JAX-RSが(GSONを手動で呼び出すのではなく)実際にシリアライゼーションを実行することの良さを回避したい場合は、StreamingOutputを使用します(つまり、アウトプッターをStreamingOutputとしてラップし、そのオブジェクトを返します)。

0
StaxMan

その背後にある完全な根拠はわかりませんが、まったく同じ問題(複数回:P)が発生したため、MediaTypeをTEXT_PLAINに変更する必要があります。

または、JAX-RSに代わりにジョブを実行させることもできます。gson.toJSON(object)を実行する代わりに、単にオブジェクトを返し、メソッドシグネチャを任意のクラスに変更します。 JAX-RS(あなたの場合はRESTEasy)は自動的にジャクソンを呼び出し(正しく設定されている場合)、オブジェクトをjsonにシリアル化します。次に、クライアント側で、Stringの代わりに同じクラスを要求すると、すべてが独自に機能するはずです。 ClientRequest/Responseについては特に詳しくないので、私が言ったように機能しない可能性があります。代わりにクライアント側でRESTEasyプロキシ機能を使用します(ProxyFactoryを参照)。それにもかかわらず、JAX-RS/RESTEasyは、クライアント側でもjsonシリアライズ/デシリアライズを自動的に実行できるため、明確な方法があります。

0
Pascal Gélinas