web-dev-qa-db-fra.com

Impossible de trouver un MessageBodyReader de type de contenu application/json et de classe Java.lang.String

J'utilise un client RestEasy avec des fournisseurs Jackson et j'obtiens l'erreur ci-dessus.

le code client est: 

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() émet une exception ClientResponseFailure avec l'erreur

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

Mon code côté serveur est ci-dessous:

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

  return gson.toJSON(object);
}
20
user1632803

Vous pouvez essayer d’ajouter la dépendance suivante à votre maven pom.

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

Le problème est que RestEasy est incapable de trouver le fournisseur Jackson. Je devais l'enregistrer manuellement avec le code suivant:

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

Tout fonctionne bien avec ça. Mais je ne suis toujours pas satisfait de la solution, Resteasy étant censé rechercher les fournisseurs et les enregistrer automatiquement.

7
user1632803

Ajoutez simplement la ligne org.jboss.resteasy.plugins.providers.jackson.ResteasyJacksonProvider dans le fichier META-INF/services/javax.ws.rs.ext.Providers, résout le problème.

Ce fichier est inclus dans resteasy-jackson-providers.jar mais le même fichier est également inclus dans un autre fichier jar, restasy-jaxrs.jar et pour un fichier jar exécutable, qui utilise ces deux fichiers jar, ils ne sont pas fusionnés!

1
MatteoM
Client client = ClientBuilder.newBuilder().register(ResteasyJacksonProvider.class).build();
1
Bruno Horta

Les choses qui ont fait fonctionner mon code sont celles que j'ai ajoutées:

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

A côté de cela, je ne sais pas pourquoi mais il semble que resteasy n'initialise pas les fournisseurs lorsque les clients ont été créés, cela signifie qu'il est nécessaire de les initier manuellement: 

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

En général, il suffit de lancer le client. 

0
Dmitry Svn

J'ai eu un problème similaire et je me suis rendu compte que le problème était lié à la version de resteasy-jackson-provider. Je viens de passer de 3.0.4.Final à 3.0.5.Final et le problème a disparu.

De plus, je me suis aussi rendu compte que si je modifiais la troisième ligne comme suit, le résultat était attendu sans qu'il soit nécessaire de changer les dépendances.

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

Si vous voulez vraiment contourner la qualité de JAX-RS en effectuant la sérialisation pour vous (au lieu d'appeler manuellement GSON), utilisez StreamingOutput (c'est-à-dire, encapsulez outputter comme StreamingOutput, renvoyez cet objet).

0
StaxMan

Je ne connais pas tout le raisonnement derrière cela, mais nous avons exactement le même problème (plusieurs fois: P) et vous devez changer le type de média en TEXT_PLAIN.

Ou vous pouvez également laisser JAX-RS faire le travail pour vous: au lieu de faire gson.toJSON (objet), renvoyez simplement un objet et modifiez la signature de votre méthode pour la classe en question. JAX-RS (RESTEasy dans votre cas) appellera automatiquement Jackson (s'il est correctement configuré) et sérialisera votre objet sur json. Ensuite, côté client, vous demanderiez la même classe au lieu de String et tout devrait fonctionner seul. Je ne suis pas particulièrement familiarisé avec ClientRequest/Response, il est donc possible que cela ne fonctionne pas comme je l'ai dit; nous utilisons plutôt la fonctionnalité proxy RESTEasy côté client (voir ProxyFactory). Néanmoins, JAX-RS/RESTEasy peut aussi json sérialiser/désérialiser automatiquement du côté client aussi, donc il y a définitivement un moyen.

0
Pascal Gélinas