¿Cómo uso el soporte JSON POJO de Jersey?
Tengo un objeto que me gustaría servir en JSON como un recurso RESTful. Tengo el soporte JSON POJO de Jersey activado así (en 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>
Pero cuando intento acceder al recurso, obtengo esta excepción:
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 clase que estoy tratando de servir no es complicada, todo lo que tiene son algunos campos finales públicos y un constructor que establece todos ellos. Los campos son todas cadenas, primitivas, clases similares a esta, o Listas de las mismas (he intentado usar listas simples en lugar de Lista genérica
Java EE 6
Jersey 1.1.5
GlassFish 3.0.1
10 answers
Jersey-json tiene una implementación JAXB. La razón por la que está recibiendo esa excepción es porque no tiene un Proveedor registrado, o más específicamente un MessageBodyWriter. Necesita registrar un contexto apropiado dentro de su proveedor:
@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();
}
}
}
Esto busca un @XmlRegistry
dentro del nombre del paquete proporcionado, que es un paquete que contiene @XmlRootElement
POJOs anotados.
@XmlRootElement
public class Person {
private String firstName;
//getters and setters, etc.
}
Luego crea una ObjectFactory en el mismo paquete:
@XmlRegistry
public class ObjectFactory {
public Person createNewPerson() {
return new Person();
}
}
Con el @Provider
registrado, Jersey debe facilitar el marshalling para usted en su recurso:
@GET
@Consumes(MediaType.APPLICATION_JSON)
public Response doWork(Person person) {
// do work
return Response.ok().build();
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-03-02 03:54:59
Puede usar @XmlRootElement
si desea usar anotaciones JAXB (vea otras respuestas).
Sin embargo, si prefiere el mapeo POJO puro, debe hacer lo siguiente (Desafortunadamente no está escrito en documentos):
- Añadir jackson*.jar a su classpath (Según lo declarado por @Vitali Bichov);
- En la web.xml, si está utilizando el parámetro init
com.sun.jersey.config.property.packages
, agregueorg.codehaus.jackson.jaxrs
a la lista. Esto incluirá proveedores JSON en la lista de análisis de Jersey.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-28 15:01:43
Esto lo hizo por mí - Jersey 2.3.1
En la web.archivo 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>
En el pom.archivo xml:
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.3.1</version>
</dependency>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-28 00:28:24
Seguí las instrucciones aquí que muestran cómo usar Jersey y Jackson POJOs(a diferencia de JAXB). También funcionó con Jersey 1.12.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-25 21:02:03
¿Por qué está utilizando los campos finales? Estoy usando jersey y tengo algunos objetos / pojos JAXB y todo lo que tenía que hacer era simplemente anotar mi método de recurso con @Produce("aplicación/json") y funciona fuera de la caja. No tuve que meterme con la web.XML. Solo asegúrate de que tus pojos estén anotados correctamente.
Aquí hay un pojo simple
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;
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-03-01 23:17:58
Probablemente ya hayas descubierto esto, pero todo lo que necesitas hacer es agregar estos frascos de jackson a tu classpath: jackson-core, jackson-jaxrs, jackson-mapper y jackson-xc
Parece que hay otro camino, como otros han señalado. Añadir esto a su " com.sol.Jersey.config.propiedad.paquetes " parámetro (si se utiliza tomcat y web.xml): "org.codehaus.jackson.jaxrs", así:
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>org.codehaus.jackson.jaxrs</param- value>
</init-param>
Hacer esto también requerirá los mismos frascos jackson en su classpath
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-20 00:09:22
Jersey 2.0 proporciona soporte para JSON usando MOXy y Jackson.
El soporte de MOXy está habilitado por defecto si el JAR existe en el classpath y el soporte de Jackson se puede habilitar usando una Característica. Todo esto se explica en detalle en el capítulo de la Guía del usuario de Jersey 2.0 sobre la unión JSON:
Https://jersey.java.net/documentation/latest/media.html#json
Para agregar soporte MOXy sin necesidad de configuración, agregue la siguiente dependencia a maven pom.xml
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
<version>2.6</version>
</dependency>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-05 14:25:33
Soy nuevo en esto, pero pude usar POJOs después de agregar el jackson-all-1.9.0.jar al classpath.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-08-27 23:00:51
Lo siguiente funcionó para mí. Estoy usandoJersey 2.7 con Jackson con Apache Felix (OSGi) ejecutándose en Tomcat6.
public class MyApplication extends ResourceConfig {
public MyApplication() {
super(JacksonFeature.class);
// point to packages containing your resources
packages(getClass().getPackage().getName());
}
}
Y luego, en su web.xml
(o en mi caso, solo un Hashtable
), usted especificaría su javax.ws.rs.Application
así
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value><MyApplication.class.getName()></param-value>
</init-param>
No es necesario especificar com.sun.jersey.config.property.pacakges
o com.sun.jersey.api.json.POJOMappingFeature
Solo asegúrese de especificar la dependencia en
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.7</version>
</dependency>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-20 20:04:30
Mover jersey-json
dependencia a la parte superior del pom.xml resolvió este problema para mí.
<dependencies>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>1.18.1</version>
</dependency>
<!-- other dependencies -->
</dependencies>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-08 11:22:15