杰西(Jersey):找不到用于Java类和MIME媒体类型application/json的消息主体编写器。

27

经过尝试后,我最终决定向您求助以解决我的问题。我看到了不同的人有着相同的问题,并尝试了他们被建议要做的所有事情,但仍然无法解决我的问题。基本上,我正在使用Jersey构建一个RESTful服务。对于我的客户端,我想返回一个JSON格式的对象。我阅读了不同的教程,并决定使用jersey-json-1.8库是有意义的。我像往常一样将所有东西都添加到了我的项目中并尝试运行它,但每次我调用服务(目前通过get请求)时,我都会收到HTTP错误代码500(内部服务器错误),而我的服务器则会回复找不到消息体编写器。 如果我返回XML,它就可以正常工作,一切都很好。我还尝试将jersey-json-1.8.jar复制到我的Tomcat lib文件夹中,因为我必须这样做才能使用我正在使用的mysql lib,但也没有帮助。 如果您需要更多信息,请留下评论,我会尽快提供。

我的项目设置如下: 3个不同的包 1. 我的RESTful服务 2. 我的Java工作,在那里我处理SQL连接等等。 3. 一个包,我在其中存储我需要处理并且希望以JSON格式返回的所有模型(例如测试驱动的路由)

一个Tomcat Web服务器 IDE:Eclipse 我正在使用Maven

无论我如何尝试返回这个对象,它都无法工作,并且我不断收到错误消息:

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.mykong.models.Teststrecke, and Java type class com.mykong.models.Teststrecke, and MIME media type application/json was not found

编辑: 这是我的JSON服务方法

@Path("/hellojson")
public class JSONService {


    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public ArrayList<Route> getJSONMsg()  
    {

        Route ts = new Route();
        ts.setId(1);
        ts.setName("HelloWorld");


        Route ts2 = new Route();
        ts2.setId(2);
        ts2.setName("HelloWorld");


        ArrayList<Route> availRoutes = new ArrayList<Route>();
        availRoutes.add(ts);
        availRoutes.add(ts2);


        return availRoutes;


    }
}

包com.mykong.models是否存在?还是只是复制粘贴的? - sschrass
它确实存在,我创建了它,只是这样命名而已。 - dhartwich
你能发布一下你的XML/JSON方法吗? - sschrass
可能是重复的问题:如何使用JAXB在Jersey 1.6中生成JSON输出 - rds
9个回答

50
尝试将Genson库添加到您的类路径中http://owlike.github.io/genson/。它是一个json<>java流和数据绑定api。它与jersey很好地集成,只需要0配置即可运行。Jersey检测到库在您的类路径中,并通过委托给Genson启用json映射。

4
对于这个解决方案我给一个赞。但是我真的很想知道为什么这没有被记录下来。我对jersey没有记录这个感到非常恼火。 - Akshay
1
@Akshay 我同意。Jersey是第一个让我在尝试使用时真正感到愤怒的软件项目。他们的文档很糟糕。前两章(是的,他们需要“章节”!)是关于设置Maven的。 - Brandon
2
在使用genson时,不需要使用jersey-json。您还可以从方法定义中删除@Consumes:(MediaType.APPLICATION_JSON)。 - Mohit Gupta

16

将这些依赖项包含在您的POM.xml中并运行Maven -> 更新

<dependency>
    <groupId>com.sun.jersey</groupId>
    <artifactId>jersey-json</artifactId>
    <version>1.18.1</version>
</dependency>
<dependency>
   <groupId>com.owlike</groupId>
   <artifactId>genson</artifactId>
   <version>0.99</version>
</dependency>

3
只使用genson就可以了,不需要jersey-json。 - eugen

12

添加以下依赖项解决了我的问题。根据@eugen的建议,我尝试添加Genson依赖项,它帮助消除了异常,但由于某些原因,我的服务器仍然抛出400错误的请求。看来Genson无法正确流式传输JSON请求。但是以下依赖项可以正常工作。希望这能帮助其他人,因为这个问题让我感到疯狂!

<dependency>
  <groupId>com.fasterxml.jackson.jaxrs</groupId>
  <artifactId>jackson-jaxrs-json-provider</artifactId>
  <version>2.3.0</version>
</dependency>

你用的是 Genson 的哪个版本? - eugen
看起来很奇怪,你应该在邮件列表上报告,并提供更多关于你遇到的问题的细节。 - eugen
使用jackson-jaxrs-json-provider 2.9.1版本对我有效。 - Asanke
还尝试了使用genson 1.4进行序列化,但出现了相同的问题。 - Victor
Genson 可能与 Jersey 冲突。对我来说解决方法是 https://dev59.com/eGct5IYBdhLWcg3wUb1-。 - Victor

3
jersey-json 依赖项移到 pom.xml 的顶部,解决了我的问题。
<dependencies>
  <dependency>
    <groupId>com.sun.jersey</groupId>
    <artifactId>jersey-json</artifactId>
    <version>1.18.1</version>
  </dependency>

  <!-- other dependencies -->

</dependencies>

2

在包资源管理器中查看“Maven Dependencies”,如果看不到“jersey-bundle-1.8.jar”或者这个文件夹,那么你可能只是指定了“jersey-server”。请在pom.xml中将依赖项更改为“jersey-bundle”,然后它应该可以工作了。


1
这个问题早已被提出,但对于正在阅读的人,请注意Jersey Servlet容器有它自己的POJO映射器。 通过将以下内容添加到您的web.xml文件中启用它。
<init-param>
    <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
    <param-value>true</param-value>
</init-param>

我注意到jersey和genson在对象映射方面存在一些差异。例如,如果一个类有一个类型为A的字段,该字段设置为B的实例,而B扩展了A,则genson将无法正确序列化B,而jersey可以。


Genson可以“正确地”序列化它,它默认使用编译时信息。要使用运行时信息,请使用GensonBuilder.useRuntimeType(true),参见http://owlike.github.io/genson/Documentation/Configuration/。 - eugen
谢谢提供信息。使用Genson相比Jersey的映射器有哪些好处? - allenwoot
首先,没有 Jersey Mapper,它只是一个使用 Jackson 的模块。人们转向它的主要原因是它可以直接与 Jersey 配合使用。您应该查看网站,看看是否有您感兴趣的功能,并自行判断其优点 :) 快速列表:支持带参数的构造函数鼓励不可变性、JAXB 注释、Scala、实现 JSR353、多态类型的序列化/反序列化(在反序列化时不会丢失具体类)、出色的可配置性和模块化以插入新组件等。 - eugen

1

Jersey 2.4:我也遇到了这个问题,并在此发布以帮助其他人。我从Jersey API规范中获取了有关JSON集成的信息:(https://jersey.java.net/documentation/latest/user-guide.html#json

我使用Jettison将其与Jersey和JSON进行集成。但是,即使添加了所有库,我仍然会收到错误消息:未找到Java类和MIME媒体类型应用程序/JSON的消息主体编写器。

一切都取决于添加正确的库以及注册功能。除了Jersey提供的所有其他库之外,我还添加了一个额外的库:jersey-media-json-jettison-2.4.jar。并添加了以下代码来注册Jettison Feature。

   public class MyApplication extends ResourceConfig{
      public MyApplication() {
          register(JettisonFeature.class);
          packages("org.XXX.XXX.XXX");   
    }

0

移除 @Produces(MediaType.APPLICATION_JSON); 并使用 JSONLibraries.zip 文件将您的数据转换为 JSON 格式。它完美地工作了。上述代码的问题在于它使用了 Maven 和 Jackson 的组合。因此,当您仅使用 Jersey 时,无法找到 APPLICATION_JSON。

我曾经处理过关于 to/from JSON 转换的问题,它给了我同样的错误。我尝试了这个解决方案,它可以正常工作。

代码:

@Path("/hellojson")
public class JSONService {

    @GET
    public ArrayList<Route> getJSONMsg()  
    {

        Route ts = new Route();
        ts.setId(1);
        ts.setName("HelloWorld");

        Route ts2 = new Route();
        ts2.setId(2);
        ts2.setName("HelloWorld");

        ArrayList<Route> availRoutes = new ArrayList<Route>();
        availRoutes.add(ts);
        availRoutes.add(ts2);

        return JSONObject.fromObject(availRoutes.toString()));
    }
}

0
以上问题将通过使用jackson库而不是genson得到解决。
    <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-mapper-asl</artifactId>
        <version>1.9.0</version>
    </dependency>


    <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.9.2</version>
    </dependency>

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

就像我的情况一样,genson在响应中提供了一个空的json,但如果我们将json转换为字符串,则会很好。但是,这将创建一个不希望的输出,因为在响应中您将获得一个字符串而不是json。所以最好使用jackson库,它可以轻松地完成。

注意:只有在类实现Serializable接口时,Jackson才会将响应转换为json。因此,如果您要发送JSONObject,则最好发送JSONObject列表。


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