40 votes

Comment utiliser le support Jersey JSON POJO?

J'ai un objet que j'aimerais servir en JSON comme une bonne ressource. J'ai Jersey JSON POJO soutien excité comme (dans web.xml):

<servlet>  
    <servlet-name>Jersey Web Application</servlet-name>  
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</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>  

Mais quand j'essaie d'accéder à la ressource, j'ai 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é, tout ce qu'il a quelques public final champs et un constructeur qui définit tous les d'entre eux. Les champs sont toutes les chaînes, les primitives, les classes similaires à celui-ci, ou des Listes de celle-ci (j'ai essayé à l'aide de la plaine des Listes au lieu de générique List<T>s, en vain). Personne ne sait ce qui donne? Merci!

Java EE 6

Maillot 1.1.5

GlassFish 3.0.1

16voto

gamliela Points 619

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

Toutefois, si vous préférez le mappage POJO pur, vous devez procéder comme suit (malheureusement, il n’est pas écrit dans la documentation):

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

13voto

yann-h Points 71

Cela l’a fait pour moi - Jersey 2.3.1

Dans le fichier web.xml:

 <servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value><my webapp packages>;org.codehaus.jackson.jaxrs</param-value>
</init-param>
</servlet>
 

Dans le fichier pom.xml:

 <dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.3.1</version>
</dependency>
 

12voto

hisdrewness Points 2643

Jersey-json a un JAXB mise en œuvre. La raison pour laquelle vous êtes l'obtention de cette exception, c'est parce que vous ne disposez pas d'un Fournisseur enregistré, ou plus précisément un MessageBodyWriter. Vous devez vous inscrire à un contexte approprié à l'intérieur de votre fournisseur de:

@Provider
public class JAXBContextResolver implements ContextResolver<JAXBContext> {
    private final static String 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 ressemble à un @XmlRegistry dans les nom de package, qui est un package qui contient @XmlRootElement annoté Pojo.

@XmlRootElement
public class Person {

    private String firstName;

    //getters and setters, etc.
}

puis de créer un ObjectFactory dans le même paquet:

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

Avec l' @Provider enregistré, Jersey devrait faciliter le regroupement pour vous dans vos ressources:

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

10voto

bytesmith Points 101

J'ai suivi les instructions ici qui montrent comment utiliser POJO Jersey et Jackson (par opposition à JAXB). Cela fonctionnait également avec Jersey 1.12.

3voto

Ricardo Riveros Points 150

Pourquoi utilisez-vous les champs finaux? J'utilise jersey et j'ai quelques objets / pojos JAXB et tout ce que je devais faire était simplement d'annoter ma méthode de ressource avec @Produces ("application / json") et cela fonctionne immédiatement. Je n'ai pas eu à jouer avec le web.xml. Assurez-vous simplement que vos pojos sont correctement annotés.

Voici un simple pojo

 package test;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class SampleJaxbObject {

    private String field1;

    private Integer field2;

    private String field3;

    public String getField1() {
        return field1;
    }

    public void setField1(String field1) {
        this.field1 = field1;
    }

    public Integer getField2() {
        return field2;
    }

    public void setField2(Integer field2) {
        this.field2 = field2;
    }

    public String getField3() {
        return field3;
    }

    public void setField3(String field3) {
        this.field3 = field3;
    }


}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X