找不到针对媒体类型= application / json的MessageBodyWriter


68

在将JAX-RS服务用作JSON时遇到了问题。

下面,我添加了我的代码。

这是我的服务班级:

//Sets the path to base URL + /hello
@Path("/hello") 
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public class Hello {

    @GET
    @Produces("application/json")
    public Student getStudent() {

        Student s = new Student();
        s.first_name = "Test First Name !!!";
        s.last_name = "Test Last Name!!!";

        return s;
    }

Student 我正在尝试从服务中获得的课程:

@XmlRootElement
public class Student implements Serializable {

    public String first_name;
    public String last_name;

    public String getFirst_name() {
        return first_name;
    }

    public void setFirst_name(String first_name) {
        this.first_name = first_name;
    }

    public String getLast_name() {
        return last_name;
    }

    public void setLast_name(String last_name) {
        this.last_name = last_name;
    }

    public Student()
    {
        first_name = "Fahad";
        last_name = "Mullaji";
    }
}

服务端的Web XML。

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    id="WebApp_ID" version="3.0">
    <display-name>com.vogella.jersey.first</display-name>
    <servlet>
        <servlet-name>Jersey REST Service</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <!-- Register resources and providers under com.vogella.jersey.first package. -->
        <init-param>
            <param-name>jersey.config.server.provider.packages</param-name>
            <param-value>com.vogella.jersey.first</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 REST Service</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>
</web-app> 

我不知道如何解决此问题。我正在使用SOAP UI来测试JSON响应,但我认为应该没关系。

我读过很多地方,需要在下面添加代码。但是我不知道在哪里。我没有使用Maven进行构建。

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

服务器正在寻找将Student对象解析为JSON的函数,但无法为其找到函数或jar文件。我添加了Genson,Moxy,RESTEasy和Jackson的罐子,但我认为这就是问题所在。我想我缺少映射的地方。


你怎么建的
约翰·阿门特

我关注了vogella.com/tutorials/REST/article.html。他没有提到有关MAVEN或ANT的建筑服务的任何事情。我是否应该使用任何东西进行建筑。感谢回复。
Fahad Mullaji 2014年

Answers:


116

我能够通过安装jersey-media-json-jackson进行修复

将依赖项添加到pom.xml

<dependency>
  <groupId>org.glassfish.jersey.media</groupId>
  <artifactId>jersey-media-json-jackson</artifactId>
  <scope>runtime</scope>
</dependency>

8
谢谢!其他人,别忘了添加version
asgs 2013年


14
为什么此解决方案有效。我为什么要盲目地将其放入pom中。
orange14

1
请注意,默认情况下,Glassfish / Payara使用MOXy作为JSON序列化程序,这会覆盖默认行为
Jakob

OP明确表示他们没有使用Maven。该问题的正确答案将显示所有需要的罐子。然后为Maven用户添加一个额外点,他们可以使用此依赖关系。然后还解释为什么需要这些,即解释有关实体提供者。
Paul Samsotha

60

您必须创建空的构造函数,因为JAX-RS会初始化类...您的构造函数必须没有参数:

@XmlRootElement
public class Student implements Serializable {

    public String first_name;
    public String last_name;

    public String getFirst_name() {
        return first_name;
    }

    public void setFirst_name(String first_name) {
        this.first_name = first_name;
    }

    public String getLast_name() {
        return last_name;
    }

    public void setLast_name(String last_name) {
        this.last_name = last_name;
    }

    public Student()
    {
        first_name = "Fahad";
        last_name = "Mullaji";
    }


 public Student()
    {
    }
}

4
我有同样的问题,我的代码,并通过添加一个空的构造解析
asad.qazi

2
辉煌!为什么这不是公认的答案,这超出了我的范围。
马修·奥克利

1
这应该是正确的答案。无论如何,您介意解释为什么我们在这里需要一个空的构造函数吗?
dkonayuki

@dkonayuki我不确定100%,但是我认为作者打印对象的方式是使用空构造函数构造该对象,并通过反射查找所有方法属性并在其上调用“ getX”。这就是为什么如果您没有空的构造函数,那么它将不起作用,并且如果您没有getter,则该属性将不会被打印。
tomidelucca

我们需要xmlroot来响应json吗?
BlueDolphin

20

我处于相同的情况下
-我没有使用Maven或Ant,
-我在Jersey上完成了Vogella教程
并且-MessageBodyWriter在尝试使用时出现错误@Produces(MediaType.APPLICATION_JSON)

@peeskillet的此答案解决了该问题-您必须使用FasterXML Jackson下载页面上提供的Jackson * .jar文件。您将需要这些core文件以及这些jaxrs文件。

WebContent/WEB-INF/lib按照上述教程将它们添加到我的Jersey * .jar文件所在的文件夹中,并对下面的web.xml文件进行了较小的更改(同样,最初由@peeskillet共享):

<param-name>jersey.config.server.provider.packages</param-name>
<param-value>
    your.other.package.here, com.fasterxml.jackson.jaxrs.json 
</param-value>

重要的是com.fasterxml.jackson.jaxrs.json


我认为我也需要解决相同的问题,但是我不确定“ your.other.package.here”是指什么?
jsh6303

定义Java服务控制器和端点的一个或多个软件包的名称。例如,我可以有一个“ login”包,其中包含一个用于登录的路由的类。因此,“ your.other.package.here”将是“ login”
amess 2015年

1
先生,你应该得到奖杯。感谢您提到这一部分:your.other.package.here,com.fasterxml.jackson.jaxrs.json正是我所缺少的。
Mouhammed Soueidane '16

1
非常感谢。您在下周保存了下来(我花了两天时间通过weblogic将球衣从1升级到2)
Ismail Sahin

1
这对我有用。它的代码版本类似于:ResourceConfig jerseyConfig = new ResourceConfig(); jerseyConfig.packages("com.dataminr.eawatcher", "com.fasterxml.jackson.jaxrs.json"); ServletContainer servletContainer = new ServletContainer(jerseyConfig);
罗伯特·弗雷泽

14

取消注释以下代码有助于

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

在基于Maven的项目中pom.xml中存在的错误为我解决了此错误。


OP明确表示他们没有使用Maven,因此为负1。
Paul Samsotha

12

下面应该在您的pom.xml中,高于其他jersy / jackson依赖项。在我的情况下,它如下jersy-client dep-cy,我没有找到MediaBodyWriter的媒体类型= application / json。

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

2
谢谢,这对我有用。之后,转到项目设置并选择所有jar文件,然后选择添加到web-inf / lib文件夹并重建。(使用intellij):)
Developine

OP明确表示他们没有使用Maven,因此为负1。
Paul Samsotha

1
加1,因为我在使用Maven时遇到了相同的问题,而omilus解决方案解决了我的问题
Pierluigi Vernetto,

6

要解决此问题,请尝试以下操作。为我工作。

pom.xml中添加以下依赖项

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

并确保Model类不包含arg构造函数

 public Student()
    {
    }

OP特别指出他们未使用Maven,因此减号为1,且OP已具有无参数构造函数。
Paul Samsotha

2

我认为可能是您应该尝试将数据转换为json格式。可以通过使用gson lib来完成。尝试以下类似的方法。

我不知道这是否是最好的解决方案,但是您可以这样做。它对我有用

例如:

@GET
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public Response info(@HeaderParam("Accept") String accept) {
    Info information = new Info();
    information.setInfo("Calc Application Info");
    System.out.println(accept);
    if (!accept.equals(MediaType.APPLICATION_JSON)) {
        return Response.status(Status.ACCEPTED).entity(information).build();
    } else {
        Gson jsonConverter = new GsonBuilder().create();
        return Response.status(Status.ACCEPTED).entity(jsonConverter.toJson(information)).build();
    }
}

1
尽管这可能有效,但这不是一个非常优雅的解决方案。将Java对象转换为JSON的工作可以由Jersey完成(这就是使用这种框架的全部目的),因此请不要自己做。
sleske

0

以我的经验,此错误非常常见,由于某些原因,jersey有时在解析自定义Java类型时遇到问题。通常,您要做的就是确保遵守以下三个条件:

  1. 如果使用maven或添加到构建路径中,则pom.xml中包含jersey-media-json-jackson。
  2. 您正在尝试反序列化的数据类型中有一个空的构造函数;
  3. 您在类和字段级别为您的自定义数据类型(xmlelement和/或jsonproperty)添加了相关注释;

但是,我遇到了仅仅这样做还不够的情况。然后,您总是可以将自定义数据类型包装在GenericEntity中,然后将其传递给ResponseBuilder:

GenericEntity<CustomDataType> entity = new GenericEntity<CustomDataType>(myObj) {};
return Response.status(httpCode).entity(entity).build();

这样,您将尝试帮助球衣为您的对象找到正确的/相关的序列化提供程序。好吧,有时这还不够。以我为例,我试图从自定义数据类型生成文本/纯文本。从理论上讲,球衣应该使用StringMessageProvider,但是由于某种原因,我无法发现它给了我这个错误:

org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyWriter not found for media type=text/plain

因此,为我解决问题的是使用杰克逊的writeValueAsString()进行自己的序列化。我对此并不感到骄傲,但是最终我可以提供一个可以接受的解决方案。



0

您必须使用将响应转换为JSON Gson.toJson(object)

例如:

return Response.status(Status.OK).entity(new Gson().toJson(Student)).build();
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.