我如何使用Jersey JSON POJO支持?

Nic*_*ick 40 java rest json jersey java-ee

我有一个对象,我想在JSON中作为RESTful资源提供服务.我打开了Jersey的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>  
Run Code Online (Sandbox Code Playgroud)

但是当我尝试访问该资源时,我得到了以下异常:

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
...
Run Code Online (Sandbox Code Playgroud)

我正在尝试提供的类并不复杂,所有它都是一些公共final字段和一个设置所有它们的构造函数.这些字段都是字符串,基元,与此类似的类或其列表(我尝试使用普通列表而不是通用List <T>,但无济于事).有谁知道是什么给出的?谢谢!

Java EE 6

泽西岛1.1.5

GlassFish 3.0.1

gam*_*ela 15

@XmlRootElement如果要使用JAXB注释,可以使用(请参阅其他答案).

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

  1. 将jackson*.jar添加到您的类路径中(如@Vitali Bichov所述);
  2. 在web.xml中,如果您使用的是com.sun.jersey.config.property.packagesinit参数,请添加org.codehaus.jackson.jaxrs到列表中.这将包括Jersey的扫描列表中的JSON提供程序.

  • 天哪,谢谢.扫描的神奇额外包为我修复了它.我已经关注了有关课程路径和手动提供者注册的所有其他相关帖子.再次感谢. (2认同)

his*_*ess 12

Jersey-json有一个JAXB实现.您获得该异常的原因是您没有注册Provider,或者更具体地说是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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

@XmlRootElement
public class Person {

    private String firstName;

    //getters and setters, etc.
}
Run Code Online (Sandbox Code Playgroud)

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

@XmlRegistry
public class ObjectFactory {
   public Person createNewPerson() {
      return new Person();
   }
}
Run Code Online (Sandbox Code Playgroud)

通过@Provider注册,Jersey应该为您的资源中的编组提供便利:

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

  • 只是为了记录 - 这个答案不再适用于泽西岛的v1.18.您不需要编写自己的MessageBodyWriter,并且@GET方法的返回类型可以是POJO对象. (13认同)
  • 仅供参考,如果使用maven,这将为您提供:`<dependency> <groupId> com.sun.jersey </ groupId> <artifactId> jersey-json </ artifactId> <version> 1.8 </ version> </依赖>` (8认同)

小智 11

这样做对我来说 - 泽西岛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>
Run Code Online (Sandbox Code Playgroud)

在pom.xml文件中:

<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.3.1</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

  • 这对我有用,只有一个修正,param-name必须是com.sun.jersey.config.property.packages (2认同)

小智 10

我按照这里的说明显示了如何使用Jersey和Jackson POJO(而不是JAXB).它也适用于Jersey 1.12.