Comment utiliser le support JSON POJO de Jersey?

J’ai un object que je voudrais utiliser dans JSON en tant que ressource RESTful. J’ai le support JSON POJO de Jersey activé comme ça (dans web.xml):

 Jersey Web Application com.sun.jersey.spi.container.servlet.ServletContainer  com.sun.jersey.api.json.POJOMappingFeature true  1  

Mais quand j’essaie d’accéder à la ressource, j’obtiens cette exception:

 SEVERE: A message body writer for Java type, class com.example.MyDto, and MIME media type, application/json, was not found SEVERE: Mapped exception to response: 500 (Internal Server Error) javax.ws.rs.WebApplicationException ... 

La classe que j’essaie de servir n’est pas compliquée, il ne contient que des champs finaux publics et un constructeur qui les définit tous. Les champs sont tous des chaînes, des primitives, des classes similaires à celle-ci, ou des listes de celles-ci (j’ai essayé d’utiliser des listes simples au lieu de la liste générique , en vain). Est-ce que quelqu’un sait ce qui donne? Merci!

Java EE 6

Jersey 1.1.5

GlassFish 3.0.1

Jersey-json a une implémentation JAXB. La raison pour laquelle vous obtenez cette exception est que vous n’avez pas un fournisseur enregistré, ou plus précisément un MessageBodyWriter . Vous devez enregistrer un contexte approprié dans votre fournisseur:

 @Provider public class JAXBContextResolver implements ContextResolver { private final static Ssortingng ENTITY_PACKAGE = "package.goes.here"; private final static JAXBContext context; static { try { context = new JAXBContextAdapter(new JSONJAXBContext(JSONConfiguration.mapped().rootUnwrapping(false).build(), ENTITY_PACKAGE)); } catch (final JAXBException ex) { throw new IllegalStateException("Could not resolve JAXBContext.", ex); } } public JAXBContext getContext(final Class type) { try { if (type.getPackage().getName().contains(ENTITY_PACKAGE)) { return context; } } catch (final Exception ex) { // trap, just return null } return null; } public static final class JAXBContextAdapter extends JAXBContext { private final JAXBContext context; public JAXBContextAdapter(final JAXBContext context) { this.context = context; } @Override public Marshaller createMarshaller() { Marshaller marshaller = null; try { marshaller = context.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); } catch (final PropertyException pe) { return marshaller; } catch (final JAXBException jbe) { return null; } return marshaller; } @Override public Unmarshaller createUnmarshaller() throws JAXBException { final Unmarshaller unmarshaller = context.createUnmarshaller(); unmarshaller.setEventHandler(new DefaultValidationEventHandler()); return unmarshaller; } @Override public Validator createValidator() throws JAXBException { return context.createValidator(); } } } 

Cela recherche un @XmlRegistry dans le nom du package fourni, qui contient un paquet contenant des @XmlRootElement annotés @XmlRootElement.

 @XmlRootElement public class Person { private Ssortingng firstName; //getters and setters, etc. } 

puis créez une ObjectFactory dans le même package:

 @XmlRegistry public class ObjectFactory { public Person createNewPerson() { return new Person(); } } 

Avec le @Provider enregistré, Jersey devrait vous faciliter la @Provider dans votre ressource:

 @GET @Consumes(MediaType.APPLICATION_JSON) public Response doWork(Person person) { // do work return Response.ok().build(); } 

Vous pouvez utiliser @XmlRootElement si vous souhaitez utiliser des annotations JAXB (voir les autres réponses).

Toutefois, si vous préférez un mappage pur POJO, vous devez effectuer les opérations suivantes (malheureusement, cela n’est pas écrit dans docs):

  1. Ajoutez jackson * .jar à votre classpath (comme indiqué par @Vitali Bichov);
  2. Dans web.xml, si vous utilisez le paramètre d’initialisation com.sun.jersey.config.property.packages , ajoutez org.codehaus.jackson.jaxrs à la liste. Cela inclura les fournisseurs JSON dans la liste d’parsing de Jersey.

Cela l’a fait pour moi – Jersey 2.3.1

Dans le fichier web.xml:

  Jersey Web Application org.glassfish.jersey.servlet.ServletContainer  jersey.config.server.provider.packages ;org.codehaus.jackson.jaxrs   

Dans le fichier pom.xml:

  org.glassfish.jersey.media jersey-media-json-jackson 2.3.1  

J’ai suivi les instructions ici qui montrent comment utiliser les POJO Jersey et Jackson (par opposition à JAXB). Il a également fonctionné avec Jersey 1.12.

Pourquoi utilisez-vous les champs finaux? J’utilise jersey et j’ai quelques objects / pojos JAXB et tout ce que j’avais à faire était d’annoter simplement ma méthode de ressource avec @Produces (“application / json”) et ça marche immédiatement. Je n’ai pas eu à jouer avec le web.xml. Assurez-vous simplement que vos pojos sont annotés correctement.

Voici un simple pojo

 package test; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement public class SampleJaxbObject { private Ssortingng field1; private Integer field2; private Ssortingng field3; public Ssortingng getField1() { return field1; } public void setField1(Ssortingng field1) { this.field1 = field1; } public Integer getField2() { return field2; } public void setField2(Integer field2) { this.field2 = field2; } public Ssortingng getField3() { return field3; } public void setField3(Ssortingng field3) { this.field3 = field3; } } 

Vous avez probablement déjà compris cela, mais tout ce que vous avez à faire est d’append ces jars jackson à votre chemin de classe: jackson-core, jackson-jaxrs, jackson-mapper et jackson-xc

Il semble qu’il y ait une autre façon, comme d’autres l’ont noté. Ajoutez ceci à votre paramètre “com.sun.jersey.config.property.packages” (si vous utilisez tomcat et web.xml): “org.codehaus.jackson.jaxrs”, comme ceci:

  com.sun.jersey.config.property.packages org.codehaus.jackson.jaxrs  

Cela nécessitera également les mêmes pots jackson sur votre classpath

Jersey 2.0 prend en charge JSON en utilisant MOXy an Jackson.

Le support MOXy est activé par défaut si le fichier JAR existe dans le chemin de classe et que le support Jackson peut être activé à l’aide d’une fonctionnalité. Ceci est expliqué en détail dans le chapitre Jersey 2.0 User Guide sur la liaison JSON:

https://jersey.java.net/documentation/latest/media.html#json

Pour append un support MOXy sans avoir besoin de configuration, ajoutez la dépendance suivante à vous pom.xml

  org.glassfish.jersey.media jersey-media-moxy 2.6  

Je suis nouveau à cela, mais j’ai pu utiliser des POJO après avoir ajouté jackson-all-1.9.0.jar au classpath.

Ce qui suit a fonctionné pour moi. J’utilise Jersey 2.7 avec Jackson avec Apache Felix (OSGi) sous Tomcat6.

 public class MyApplication extends ResourceConfig { public MyApplication() { super(JacksonFeature.class); // point to packages containing your resources packages(getClass().getPackage().getName()); } } 

Et puis, dans votre web.xml (ou dans mon cas, juste un Hashtable ), vous spécifiez votre application javax.ws.rs.Application ainsi

  javax.ws.rs.Application   

Nul besoin de spécifier com.sun.jersey.config.property.pacakges ou com.sun.jersey.api.json.POJOMappingFeature

Assurez-vous de spécifier la dépendance sur

  org.glassfish.jersey.media jersey-media-json-jackson 2.7  

Déplacer la dépendance jersey-json vers le haut du fichier pom.xml a résolu ce problème pour moi.

   com.sun.jersey jersey-json 1.18.1