How do I use the Jersey JSON POJO support?
You can use @XmlRootElement
if you want to use JAXB annotations (see other answers).
However, if you prefer pure POJO mapping, you must do the following (Unfortunately it isn't written in docs):
- Add jackson*.jar to your classpath (As stated by @Vitali Bichov);
- In web.xml, if you're using
com.sun.jersey.config.property.packages
init parameter, addorg.codehaus.jackson.jaxrs
to the list. This will include JSON providers in the scan list of Jersey.
Jersey-json has a JAXB implementation. The reason you're getting that exception is because you don't have a Provider registered, or more specifically a MessageBodyWriter. You need to register a proper context within your provider:
@Providerpublic 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(); } }}
This looks up for an @XmlRegistry
within the provided package name, which is a package that contains @XmlRootElement
annotated POJOs.
@XmlRootElementpublic class Person { private String firstName; //getters and setters, etc.}
then create an ObjectFactory in the same package:
@XmlRegistrypublic class ObjectFactory { public Person createNewPerson() { return new Person(); }}
With the @Provider
registered, Jersey should facilitate the marshalling for you in your resource:
@GET@Consumes(MediaType.APPLICATION_JSON)public Response doWork(Person person) { // do work return Response.ok().build();}
This did it for me - Jersey 2.3.1
In the web.xml file :
<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>
In the pom.xml file :
<dependency><groupId>org.glassfish.jersey.media</groupId><artifactId>jersey-media-json-jackson</artifactId><version>2.3.1</version></dependency>