Jersey + Json媒体类型应用程序/ json未找到。

17

我正在尝试使用简单的Jersey + JSON示例,但是我出现了以下错误

Java类com.test.jsonexample的消息体编写器和MIME媒体类型application/json未找到

我添加了以下jar文件以获得适当的结果

asm-3.1.jar
jackson-core-asl-1.9.9.jar
jackson-jaxrs-1.9.9.jar
jackson-mapper-asl-1.9.9.jar
jackson-xc-1.9.9.jar
jersey-client-1.9.jar
jersey-core-1.9.1.jar
jersey-json-1.9.jar
jersey-server-1.9.1.jar
jettison-1.3.2.jar
jsr311-api-1.1.1.jar

为什么我会收到这种类型的错误?错误日志在这里:

SEVERE: Mapped exception to response: 500 (Internal Server Error)
javax.ws.rs.WebApplicationException: com.sun.jersey.api.MessageException: A message body writer for Java class com.test.Jsonexample, and Java type class com.test.Jsonexample, and MIME media type application/json was not found
    at com.sun.jersey.spi.container.ContainerResponse.write(ContainerResponse.java:285)
    at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1437)
    at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1349)
    at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1339)
    at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416)
    at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:537)
    at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:708)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1001)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:579)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <display-name>TestJaxRs</display-name>

    <servlet>
        <servlet-name>jersey-serlvet</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.rest</param-value>
        </init-param>
        <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>

    <servlet-mapping>
        <servlet-name>jersey-serlvet</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>

</web-app>

JsonExample.java

@XmlRootElement  
public class JsonExample {

    String title;
    String singer;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getSinger() {
        return singer;
    }

    public void setSinger(String singer) {
        this.singer = singer;
    }

    @Override
    public String toString() {
        return "JsonExample [title=" + title + ", singer=" + singer + "]";
    }

}

和Json服务

@Path("/json/metallica")
public class JSONService {

    @GET
    @Path("/get")
    @Produces(MediaType.APPLICATION_JSON)
    public JsonExample getTrackInJSON() {

        JsonExample json = new JsonExample();
        json.setTitle("Enter Sandman");
        json.setSinger("Metallica");

        return json;

    }

    @POST
    @Path("/post")
    @Consumes(MediaType.APPLICATION_JSON)
    public Response createTrackInJSON(JsonExample track) {

        String result = "Track saved : " + track;
        return Response.status(201).entity(result).build();
    }

如果我做错了什么,请给我建议。

15个回答

15

这个问题已经通过jersey-bundle-1.8.jar得到了解决。


2
我在我的pom.xml中包含了“jersey-json”工件,这解决了我的问题。在非maven项目中,您可以通过将“jersey-json.jar”文件包含在类路径中来解决该问题。 - Hemant G
1
添加 "jersey-json" API 可以解决这个问题。 <dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-bundle</artifactId> <version>1.18.1</version> </dependency> - Ahmet Karakaya
编译 "com.sun.jersey:jersey-bundle:1.18.1" 的代码。 - Lau Llobet
@Ajay - 请在你的回答中提到Jersey Bundle应该独立于其他Jersey依赖项(客户端、服务器、核心等)。忘记其他Jersey依赖项可能会产生未知行为 - 我曾经遇到过这种情况。没有报告错误,但由于某种原因,对象未被序列化并且请求发送了空主体。 - Victor
我遇到了相同的问题,因为我没有放置我的“response(entity.toString).build.”。 “toString”是关键。 - Big Zed

10

通过在我的pom.xml中添加以下内容解决了问题:

    <dependency>
        <groupId>com.owlike</groupId>
        <artifactId>genson</artifactId>
        <version>0.99</version>
    </dependency>

文档可以在以下网址找到:https://code.google.com/p/genson/


使用genson发送POST请求时会导致空的请求体。 - Victor

4
请添加以下依赖项以解决问题。
"javax.ws.rs.WebApplicationException: com.sun.jersey.api.MessageException: A message body writer for Java class com.test.Jsonexample, and Java type class com.test.Jsonexample, and MIME media type application/json was not found
    at com.sun.jersey.spi.container.ContainerResponse.write(ContainerResponse.java:285)"

解决方案:

<dependency>
    <groupId>com.sun.jersey</groupId>
    <artifactId>jersey-bundle</artifactId>
    <version>1.18</version>
</dependency>

4

首先,如果您的@POST web服务返回响应,则必须添加@Produces注释。

确保您的类路径中有jersey-json库。 尝试删除toString()方法,因为它可能会破坏bean结构格式。


问题已经通过使用jersey-bundle-1.8.jar文件得到解决。 - Ajay

3

我尝试使用'com.sun.jersey:jersey-bundle:1.19',但是没有解决问题。

在我的情况下,添加对genson的依赖解决了问题。

runtime(
        'com.owlike:genson:0.99'
)

3
如果您不使用jackson,可以尝试Genson库http://owlike.github.io/genson/。 只需在类路径中添加库,一切都应该可以正常工作,无需任何其他代码。您甚至不需要在web.xml中使用POJOMappingFeature或在您的pojo上添加@XMLRootElement! 您还可以使用jersey机制(ContextResolver)注入具有特定配置的Genson实例。

问题已经通过使用jersey-bundle-1.8.jar文件得到解决。 - Ajay

3

我已经花了整整四天的时间,搜索了数小时来解决我的POST请求完全不起作用的问题。我遇到了这个错误以及其他与MOXY相关的错误,例如classdefnotfound错误,因为stackoverflow上的人建议使用MOXY而不是Jackson。我也尝试了genson库,但没有任何区别。

最终,我完全移除了MOXY,只保留了Jackson。几个小时后,我终于找到了解决方案,让我有点生气,因为它是多么简单的一个问题。我的工作区分成了多个不同的项目,一个用于Web应用程序,其中包含Web.xml文件,另一个用于RESTful API。

我还在运行Jersey 2,这是另一个问题,因为很多关于这个问题的接受答案都只谈到Jersey 1,当我刚开始尝试解决这个问题时非常混乱。

经过数小时的尝试,最终发现问题出在这里(使用OP中发布的代码结构):

  1. You HAVE to include @XmlRootElement at the top of your POJO class, contrary to many of the examples on stackoverflow which seem to omit it.

  2. You HAVE to include the following in both the project that includes your web.xml as well as the project that includes your REST service and associated classes. Change the version which is relevant to version of Jersey you are using.

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

就这样。除了这个和你正在使用的相关Jersey库,你不需要包含任何其他内容。

我真诚地希望这能帮助其他人节省数小时的时间来解决这个问题。


2
使用jersey-bundle-1.19.1.jar(非maven),我需要删除这个内容:
<init-param>
  <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
  <param-value>true</param-value>
</init-param>

从web.xml文件中获取。

我知道文档建议这个部分是必需的,但令人惊讶的是它是问题的原因。


1
我曾遇到同样的问题,通过删除所有JSON依赖项并添加以下内容来解决了它:
com.owlike genson 0.99

1

我知道这是一个老问题,但我遇到了这个问题并尝试了所有上述解决方案,但不幸的是,它们都没有帮助到我。 我发现的是,MediaType类在两个不同的jar中定义,而在构建jar时,它采用了在另一个类中定义的类(在我的情况下,是glassfish jar)。 移除另一个jar(您也可以排除特定部分),问题就解决了。


有道理。我们遇到了同样的问题。使用jersey-bundle可以工作,但是真正的问题是jersey模块之间存在依赖冲突。 - Danilo Gomes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接