我如何使用Jersey JSON POJO支持?

我有一个对象,我想在JSON中作为一个RESTful资源。 我有泽西的JSON POJO支持像这样打开(在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> 

但是,当我尝试访问资源,我得到这个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 ... 

我试图服务的类并不复杂,只有一些公共final字段和一个构造函数来设置它们。 这些字段都是string,基本类,类似于这个,或者它们的列表(我尝试使用普通列表而不是genericsList <T> s,无济于事)。 有谁知道什么给? 谢谢!

Java EE 6

泽西岛1.1.5

GlassFish 3.0.1

Jersey-json有一个JAXB实现。 你得到这个exception的原因是因为你没有注册提供者 ,或者更确切地说是一个MessageBodyWriter 。 您需要在您的提供商中注册适当的上下文:

 @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(); } } } 

这将在提供的包名称中查找@XmlRegistry ,该包名称是包含@XmlRootElement注释的POJO的包。

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

然后在同一个包中创build一个ObjectFactory:

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

在注册了@Provider ,泽西岛应该在你的资源中促进你的编组:

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

如果您想使用JAXB注释,请使用@XmlRootElement (请参阅其他答案)。

但是,如果您更喜欢纯粹的POJO映射,则必须执行以下操作(不幸的是,它不是用docs编写的):

  1. 将jackson * .jar添加到您的类path(如@Vitali Bichov所述);
  2. 在web.xml中,如果使用的是com.sun.jersey.config.property.packages初始参数,请将org.codehaus.jackson.jaxrs添加到列表中。 这将包括泽西岛扫描列表中的JSON提供者。

这对我来说 – 泽西岛2.3.1

在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> 

在pom.xml文件中:

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

我遵循这里的说明,说明如何使用Jersey和Jackson POJO(而不是JAXB)。 它也和Jersey 1.12一起工作。

你为什么使用最后的领域? 我使用jersey,我有一些JAXB对象/ pojos和我所要做的只是注释@Produces(“应用程序/ json”)我的资源方法,它的工作方式。 我不必乱搞web.xml。 只要确保您的pojos正确注释。

这是一个简单的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; } } 

你可能已经知道了这一点,但你需要做的就是把这些jackson jar添加到你的类path中:jackson-core,jackson-jaxrs,jackson-mapper和jackson-xc

正如其他人所指出的那样,还有另一种方式。 把这个添加到你的“com.sun.jersey.config.property.packages”参数(如果使用tomcat和web.xml):“org.codehaus.jackson.jaxrs”,如下所示:

 <init-param> <param-name>com.sun.jersey.config.property.packages</param-name> <param-value>org.codehaus.jackson.jaxrs</param- value> </init-param> 

这样做也将需要类path上相同的jacksonjar

Jersey 2.0使用MOXY和Jackson提供对JSON的支持。

如果类path中存在JAR,则默认启用MOXy支持,并且可以使用function启用Jackson支持。 有关JSON绑定的“Jersey 2.0用户指南”一章中详细解释了这一点:

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

要添加MOXY支持而不需要configuration,请将以下依赖项添加到您的maven pom.xml

 <dependency> <groupId>org.glassfish.jersey.media</groupId> <artifactId>jersey-media-moxy</artifactId> <version>2.6</version> </dependency> 

我是新来的,但是我可以在将jackson-all-1.9.0.jar添加到类path后使用POJO。

以下为我工作。 我使用泽西2.7与jackson与运行在Tomcat6上的Apache Felix(OSGi)。

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

然后,在你的web.xml (或在我的情况下,只是一个Hashtable ),你可以像这样指定你的javax.ws.rs.Application

 <init-param> <param-name>javax.ws.rs.Application</param-name> <param-value><MyApplication.class.getName()></param-value> </init-param> 

无需指定com.sun.jersey.config.property.pacakgescom.sun.jersey.api.json.POJOMappingFeature

只要确保你指定依赖

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

jersey-json依赖移动到pom.xml的顶部,为我解决了这个问题。

 <dependencies> <dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-json</artifactId> <version>1.18.1</version> </dependency> <!-- other dependencies --> </dependencies>