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);
}
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>
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.
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!
Client client = ClientBuilder.newBuilder().register(ResteasyJacksonProvider.class).build();
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.
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();
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).
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.