web-dev-qa-db-fra.com

Exception Jersey: SEVERE: lecteur de corps de message pour la classe Java

J'ai un Rest WS basé sur Jersey qui produit du JSON. J'implémente un client Jersey pour appeler WS et utiliser la réponse JSON. Le code client que j'ai est ci-dessous

 WebResource r = restClient.resource (UriBuilder.fromUri ("http: // localhost /") .port (8080) .build ()); 
 String resp = r.path ("/ utilisateur"). accept (MediaType.APPLICATION_JSON) .get (String.class); 
 Utilisateur [] utilisateurs = r.path ("/ utilisateur"). accept (MediaType.APPLICATION_JSON) .get (Utilisateur []. classe); 

La 2ème ligne affiche correctement la réponse de chaîne JSON, mais la 3ème ligne pour marshal JSON vers le POJO n’a pas lieu et j’obtiens le stacktrace d’exception suivant.

 SEVERE: Lecteur de corps de message pour la classe Java [Lorg.shoppingsite.model.entity.jpa.User ;, et la classe de type Java [Lorg.shoppingsite.model.entity.jpa.User ;, et le type de support MIME application /. json n'a pas été trouvé 
 21 déc. 2011, 11:32:01 com.Sun.jersey.api.client.ClientResponse getEntity 
 SEVERE: Les lecteurs de corps de message enregistrés compatibles avec le type de support MIME sont: 
 */* -> 
 com.Sun.jersey.core.impl.provider.entity.FormProvider 
 com.Sun.jersey.core.impl.provider.entity.StringProvider 
 com.Sun.jersey.core.impl.provider.entity.ByteArrayProvider 
 com.Sun.jersey.core.impl.provider.entity.FileProvider 
 com.Sun.jersey.core.impl.provider.entity.InputStreamProvider 
 com.Sun.jersey.core.impl.provider.entity.DataSourceProvider 
 com.Sun.jersey.core.impl.provider.entity.XMLJAXBElementProvider $ General 
 com.Sun.jersey.core.impl.provider.entity.ReaderProvider 
 com.Sun.jersey.core.impl.provider.entity.DocumentProvider 
 com.Sun.jersey.core.impl.provider.entity.SourceProvider $ StreamSourceReader 
 com.Sun.jersey.core.impl.provider.entity.SourceProvider $ SAXSourceReader 
 com.Sun.jersey.core.impl.provider.entity.SourceProvider $ DOMSourceReader 
 com.Sun.jersey.core.impl.provider.entity.XMLRootElementProvider $ General 
 com.Sun.jersey.core.impl.provider.entity.XMLListElementProvider $ General 
 com.Sun.jersey.core.impl.provider.entity.XMLRootObjectProvider $ General 
 com.Sun.jersey.core.impl.provider.entity.EntityHolderReader 

J'ai les bons types de MIME dans ma demande. Mon POJO a été annoté avec XMLRootElement. Qu'est-ce que je rate. 

Je vous remercie

32
VDev

J'ai pu résoudre le problème en ajoutant la dépendance maven de jersey-json.

29
VDev

Pour que cela fonctionne, vous n'avez besoin que de deux choses. Vérifiez s'il vous manque:

  1. Tout d’abord, vous avez besoin de @XmlRootElement annotation pour votre classe d’objet/entité.
  2. Vous devez ajouter une dépendance pour jersey-json si vous manquez. Pour votre référence, j'ai ajouté cette dépendance dans mon pom.xml.

    <dependency>
        <groupId>com.Sun.jersey</groupId>
        <artifactId>jersey-json</artifactId>
        <version>1.17.1</version>
    </dependency>
    
25
user2139024

Je sais que ce post est vieux et que vous l'avez compris il y a longtemps, mais juste pour sauver ceux qui le liront quelque temps.

Vous avez probablement oublié d'ajouter une annotation à l'entité que vous transmettez au noeud final, donc Jersey ne sait pas comment traiter le POJO qu'il reçoit . Annotez le pojo avec quelque chose comme ceci: 

@XmlRootElement(name = "someName")

viens de mettre ceci

    <init-param>
        <param-name>com.Sun.jersey.api.json.POJOMappingFeature</param-name>
        <param-value>true</param-value>
    </init-param>

Si vous construisez un uberjar ou un "jar ombré", assurez-vous que vos fichiers de service meta inf sont fusionnés. (Cela m'a mordu plusieurs fois sur un projet dropwizard.)

Si vous utilisez le plugin Gradle shadowJar, vous souhaitez appeler mergeServiceFiles() dans votre cible shadowJar: https://github.com/johnrengelman/shadow#merging-service-files

Je ne sais pas quelles sont les commandes analogues pour maven ou d’autres systèmes de compilation.

8
mooreds

Nous avons également décidé d’utiliser le jersey comme solution. Mais comme nous utilisons org.JSON dans la plupart des cas, cette dépendance est inutile et nous ne nous sommes pas sentis bien. 

Nous avons donc utilisé la représentation String pour obtenir un objet org.JSON au lieu de

JSONObject output = response.getEntity(JSONObject.class); 

nous l'utilisons de cette façon maintenant: 

JSONObject output = new JSONObject(response.getEntity(String.class)); 

où JSONObject vient de org.JSON et les importations pourraient être modifiées à partir de:

-import org.codehaus.jettison.json.JSONArray;
-import org.codehaus.jettison.json.JSONException;
-import org.codehaus.jettison.json.JSONObject;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
4
Jens Peters

Ajoutez simplement les lignes ci-dessous dans votre POJO avant le début du cours et votre problème est résolu . @Produces ("application/json") @XmlRootElement Voir exemple importer javax.ws.rs.Produces; importer javax.xml.bind.annotation.XmlRootElement;

 /**
 * @author manoj.kumar
 * @email [email protected]
 */
 @Produces("application/json")
 @XmlRootElement  
 public class User {

 private String username;
 private String password;
 private String email;
 public String getUsername() {
 return username;
 }
 public void setUsername(String username) {
     this.username = username;
 }
 public String getPassword() {
     return password;
 }
 public void setPassword(String password) {
     this.password = password;
 }
 public String getEmail() {
    return email;
 }
 public void setEmail(String email) {
    this.email = email;
 }

}
add below lines inside of your web.xml
<init-param>
    <param-name>com.Sun.jersey.api.json.POJOMappingFeature</param-name>
    <param-value>true</param-value>
</init-param>  
Now recompile your webservice everything would work!!!
3
mkumar0304

Dans mon cas, j'utilise POJO. Et j’ai oublié de configurer POJOMappingFeature avec true ..__, Maycon l’a indiqué dans une réponse rapide. Cependant, certains gars pourraient avoir du mal à le configurer correctement dans web.xml, voici mon exemple.

<servlet>
    <servlet-name>Jersey Servlet</servlet-name>
    <servlet-class>com.Sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
    <init-param>
        <param-name>com.Sun.jersey.api.json.POJOMappingFeature</param-name>
        <param-value>true</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
3
James.G

Essayez d'ajouter:

<dependency>
    <groupId>com.owlike</groupId>
    <artifactId>genson</artifactId>
    <version>1.4</version>
</dependency>

De plus, ce problème peut survenir si vous utilisez HTTP GET avec le corps du message. Dans ce cas, ajouter jersey-json lib, @XmlRootElement ou modifier le fichier web.xml ne vous aidera pas. Vous devez utiliser l'URL QueryParam ou HTTP POST.

2
Justas

Il suffit de vérifier si vous utilisez différentes instances dans Eclipse. J'ai quitté toutes mes autres sessions, une construction propre a résolu le problème

0
gibsosmart

Vous devez implémenter vos propres MessageBodyReader et MessageBodyWriter pour votre classe Lorg.shoppingsite.model.entity.jpa.User

package javax.ws.rs.ext;

import Java.io.IOException;
import Java.io.InputStream;
import Java.lang.annotation.Annotation;
import Java.lang.reflect.Type;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;

public interface MessageBodyReader<T extends Object> {

    public boolean isReadable(Class<?> type, 
        Type genericType, 
        Annotation[] annotations, 
        MediaType mediaType);

    public T readFrom(Class<T> type, 
        Type genericType, 
        Annotation[] annotations, 
        MediaType mediaType, 
        MultivaluedMap<String, String> httpHeaders, 
        InputStream entityStream) throws IOException, WebApplicationException;
}

package javax.ws.rs.ext;

import Java.io.IOException;
import Java.io.OutputStream;
import Java.lang.annotation.Annotation;
import Java.lang.reflect.Type;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;

public interface MessageBodyWriter<T extends Object> {

    public boolean isWriteable(Class<?> type, 
        Type genericType, 
        Annotation[] annotations, 
        MediaType mediaType);

    public long getSize(T t, 
        Class<?> type, 
        Type genericType, 
        Annotation[] annotations, 
        MediaType mediaType);

    public void writeTo(T t, 
        Class<?> type, 
        Type genericType, 
        Annotation[] annotations, 
        MediaType mediaType, 
        MultivaluedMap<String, Object> httpHeaders, 
        OutputStream entityStream) throws IOException, WebApplicationException;
}
0
alex347

Certains peuvent être confus pourquoi ajouter jersey-json jar ne peut pas résoudre ce problème. J'ai découvert que ce bocal doit être plus récent que jersey-json-1.7.jar (1.7.0 ne fonctionne pas, mais 1.7.1 fonctionne très bien.). espérons que cela peut aider 

0
Nick Liu