如何使用 JAXB 使用 Jersey 1.6 生成 JSON 输出

Posted

技术标签:

【中文标题】如何使用 JAXB 使用 Jersey 1.6 生成 JSON 输出【英文标题】:How to produce JSON output with Jersey 1.6 using JAXB 【发布时间】:2011-08-26 23:50:03 【问题描述】:
@XmlRootElement
public class Todo 
    private String s = "test";

    public String getS() 
        return s;
    

    public void setS(String s) 
        this.s = s;
    


和服务:

@Path("/test")
public class Service 

    @GET
    @Produces(MediaType.APPLICATION_JSON )
    public List<Todo> getAllGadgets() 
        return Arrays.asList(new Todo[]  new Todo() );
    


我的 web.xml:

<servlet>
    <servlet-name>Jersey REST Service</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    <init-param>
        <param-name>com.sun.jersey.config.property.packages</param-name>
        <param-value>com.test</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>Jersey REST Service</servlet-name>
    <url-pattern>/rest/*</url-pattern>
</servlet-mapping>

如果我将 MediaType.APPLICATION_XML 设置为 Produces 注释,所有这些都可以工作。但对于 JSON,我得到以下异常:

严重:将异常映射到响应: 500内部服务器错误) javax.ws.rs.WebApplicationException: com.sun.jersey.api.MessageException:一个 Java 类的消息体编写器 java.util.Arrays$ArrayList 和 Java 键入 java.util.List, 和 MIME 媒体类型 application/json 没找到

我使用 Jersey 1.6,根据教程,JSON 格式应该可以与 JAXB 一起使用,而无需任何额外的编程。怎么了?

【问题讨论】:

【参考方案1】:

我解决了这个问题。我需要做的就是将 jersey-json-1.6.jar 库添加到项目中(这不是 jersey 的必需部分)

【讨论】:

谢谢。我一直在寻找更复杂的原因。 这对我不起作用。我仍然遇到严重问题:找不到 Java 类型、java.util.ArrayList 类和 MIME 媒体类型 application/json 的消息正文编写器。这是在运行使用 InMemoryContainer 的测试时,所以我想知道它是否与此有关。 我不得不将 jersey-server 更改为 1.9,jersey-core 1.9 和 jersey-json 更改为 1.9 jars。 应用程序/xml怎么做 使用 Maven - 我必须添加:com.sun.jersey jersey-json1.17依赖>【参考方案2】:

将以下参数添加到 web.xml 文件中的 jersey servlet,这是最新 1.x 版本的 jersey-servlet 所必需的。

    <init-param>
        <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
        <param-value>true</param-value>
    </init-param>

【讨论】:

我从接受的答案中获得了一切,并且正在使用 jersey v1.13;这就是解决我的问题的原因。谢谢!【参考方案3】:

我使用的是 Google App Engine,并且在这方面也遇到了很多困难,如果您使用 jersey-bundle-1.17.jar,那么大多数东西在您添加之前都可以正常工作

<init-param>
    <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
    <param-value>true</param-value>
</init-param>

你会收到很多奇怪的信息。这是因为你错过了一些杰克逊罐子。 如果你去jersey homepage 并下载 zip 和捆绑包。只需删除捆绑包,然后从 zip 中添加 4 个 jackson jar 到您的类路径中,您应该可以让一切正常工作。

下面添加jackson-jaxrs-1.9.2.jar解决这个错误

SEVERE: The registered message body writers compatible with the MIME media type are:
application/json ->

添加 jackson-xc-1.9.2.jar 解决以下警告

java.lang.NoClassDefFoundError: org/codehaus/jackson/xc/JaxbAnnotationIntrospector

我希望这对某人有所帮助。

【讨论】:

我使用 jackson-jaxrs 1.9.13 + cxf-bundle-jaxrs 2.7.11。我遇到的问题是第一个请求总是失败,后面的请求都是成功的。在调试过程中,我注意到像你这样的 NoClassDefFoundError 异常。添加jackson-xc-1.9.2解决问题。我认为是杰克逊依赖问题【参考方案4】:

其他答案对我不起作用,但我终于让它与 JSON 一起使用。

我正在使用 jersey-bundle-1.17.jar(也尝试将 asm-3.1.jar 和 jersey-json-1.17.jar 添加到类路径中,但仍然无法正常工作)。我终于尝试下载包含 12 个不同 jar 的 zip。一旦我将所有 12 个 jars 添加到我的类路径中,我终于摆脱了错误并且返回 JSON 效果很好。

我希望这对某人有所帮助。

更新: 这是包含 12 个 jar 文件的 zip 文件的链接:jersey-archive-1.17.zip

Maven 用户的另一个更新: 将以下内容添加到您的 pom.xml 以分别获取 12 个罐子:

    <dependency>
        <groupId>com.sun.jersey</groupId>
        <artifactId>jersey-servlet</artifactId>
        <version>1.17.1</version>
    </dependency>
    <dependency>
        <groupId>com.sun.jersey</groupId>
        <artifactId>jersey-client</artifactId>
        <version>1.17.1</version>
    </dependency>
    <dependency>
        <groupId>com.sun.jersey</groupId>
        <artifactId>jersey-json</artifactId>
        <version>1.17.1</version>
    </dependency>
    <dependency>
        <groupId>com.sun.jersey</groupId>
        <artifactId>jersey-core</artifactId>
        <version>1.17.1</version>
    </dependency>
    <dependency>
        <groupId>com.sun.jersey</groupId>
        <artifactId>jersey-server</artifactId>
        <version>1.17.1</version>
    </dependency>
    <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-core-asl</artifactId>
        <version>1.9.2</version>
    </dependency>
    <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-mapper-asl</artifactId>
        <version>1.9.2</version>
    </dependency>
    <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-jaxrs</artifactId>
        <version>1.9.2</version>
    </dependency>
    <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-xc</artifactId>
        <version>1.9.2</version>
    </dependency>
    <dependency>
        <groupId>org.codehaus.jettison</groupId>
        <artifactId>jettison</artifactId>
        <version>1.1</version>
    </dependency>
    <dependency>
        <groupId>javax.ws.rs</groupId>
        <artifactId>jsr311-api</artifactId>
        <version>1.1.1</version>
    </dependency>
    <dependency>
        <groupId>asm</groupId>
        <artifactId>asm</artifactId>
        <version>3.1</version>
    </dependency>

【讨论】:

您能否提供包含 12 个 jar 文件的 zip 文件的名称或链接? 当然可以。我刚刚添加了一个指向 zip 文件的链接。 它给了我:400 - 错误请求 哈哈,抱歉... Google 移动了文件。我在公共 Maven 2 存储库中添加了另一个引用,所以你现在应该很好了。 @tieTYT 我已经单独添加了依赖项,因此您可以将它们放入您的 pom.xml 文件中。【参考方案5】:

如果您不使用 @XmlRootElement 注释您的 POJO(或基本 POJO),则会引发 OP 列出的消息正文编写器异常。

例如:

@XmlRootElement
public class BaseBean

    private Boolean success = Boolean.TRUE;
    private String message;

    /**
     * Empty constructor to satisfy requirements of JAXRS.
     */
    public BaseBean() 

    /**
     * Returns a simple message to accompany the success/failure.
     * @return
     */
    public String getMessage()
    
        return message;
    

    /**
     * Sets the message (if required).
     * @param message
     */
    public void setMessage(String message)
    
        this.message = message;
    

    /**
     * Returns a flag indicating whether a request for content was
     * successful.
     * @return
     */
    public Boolean getSuccess()
    
        return success;
    

    /**
     * Marks the success of a request for content.
     * @param success
     */
    public void setSuccess(Boolean success)
    
        this.success = success;
    

【讨论】:

【参考方案6】:

Kamran 的回答对我有用,只是为了进一步扩展 xml:

    <servlet>
    <servlet-name>JerseyServletContainer</servlet-name>
    <servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
    <init-param>
    <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
    <param-value>true</param-value>
    </init-param>

【讨论】:

以上是关于如何使用 JAXB 使用 Jersey 1.6 生成 JSON 输出的主要内容,如果未能解决你的问题,请参考以下文章

严重:找不到媒体类型 = 应用程序/json、类型 = 类 com.jersey.jaxb.Todo、通用类型 = 类 com.jersey.jaxb.Todo 的 MessageBodyWriter

Java.util.Map to JSON Object with Jersey / JAXB / Jackson

JAXB 映射到 JSON

在哪里包含 jaxb.properties 文件?

在 Java 1.6 中为 JAX-WS 提供不同版本的 JAXB

笔记:Jersey REST 传输格式-JSON