严重错误:找不到针对媒体类型为application/json、类型为com.jersey.jaxb.Todo、泛型类型为com.jersey.jaxb.Todo的消息实体编写器。

35

我正在尝试创建一个RESTful的web服务,我已经创建了一个,但是出现了

媒体类型为application/json的MessageBodyWriter未找到的错误

我的Todo类:

package com.jersey.jaxb;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import org.pojomatic.Pojomatic;
import org.pojomatic.annotations.AutoProperty;

@XmlRootElement
@XmlType(name = "todo")
@XmlAccessorType(XmlAccessType.FIELD)
@AutoProperty
public class Todo {

    @XmlElement(name = "summary")
    private final String summary;

    @XmlElement(name = "description")
    private final String description;

    public String getSummary() {
        return summary;
    }

    public String getDescription() {
        return description;
    }

    public Todo() {
        this(new Builder());    
    }

    public Todo(Builder builder) {
        this.summary = builder.summary;
        this.description = builder.description;
    }

    @Override
    public boolean equals(Object o) {
        return Pojomatic.equals(this, o);
    }

    @Override
    public int hashCode() {
        return Pojomatic.hashCode(this);
    }

    @Override
    public String toString() {
        return Pojomatic.toString(this);
    }

    public static class Builder {
        private String description;
        private String summary;

        public Builder summary(String summary) {
            this.summary = summary;
            return this;
        }

        public Builder description(String description) {
            this.description = description;
            return this;
        }

        public Todo build() {
            return new Todo(this);
        }
    }
}

我的资源:

package com.jersey.jaxb;

import javax.ws.rs.Path;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.Produces;
import javax.ws.rs.GET;

import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;

@Path("/todo")
public class TodoResource {

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Response getTodo(){
        Todo todo = new Todo.Builder().description("My Todo Object").summary("Created").build();
        return Response.status(Status.OK).entity(todo).build();
    }

}

我的 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" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<welcome-file-list>
  <welcome-file>index.html</welcome-file>
  <welcome-file>index.htm</welcome-file>
  <welcome-file>index.jsp</welcome-file>
  <welcome-file>default.html</welcome-file>
  <welcome-file>default.htm</welcome-file>
  <welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<display-name>MyFirstWebService</display-name>
<servlet>
  <servlet-name>Jersey REST Service</servlet-name>
  <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
   <init-param>
     <param-name>jersey.config.server.provider.packages</param-name>
     <param-value>com.jersey.jaxb</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>  

我的库:

aopalliance-repackaged-2.4.0-b10.jar
asm-debug-all-5.0.2.jar
hk2-api-2.4.0-b10.jar
hk2-locator-2.4.0-b10.jar
hk2-utils-2.4.0-b10.jar
jackson-jaxrs-json-provider-2.2.3.jar
javassist-3.18.1-GA.jar
javax.annotation-api-1.2.jar
javax.inject-2.4.0-b10.jar
javax.servlet-api-3.0.1.jar
javax.ws.rs-api-2.0.1.jar
jaxb-api-2.2.7.jar
jersey-client.jar
jersey-common.jar
jersey-container-servlet.jar
jersey-container-servlet-core.jar
jersey-guava-2.17.jar
jersey-media-jaxb.jar
jersey-server.jar
org.osgi.core-4.2.0.jar
osgi-resource-locator-1.0.1.jar
persistence-api-1.0.jar
validation-api-1.1.0.Final.jar
当我在Tomcat服务器上运行此应用程序并运行以下内容时: http://localhost:8080/MyFirstWebService/rest/todo 我会得到以下错误:

严重错误:未找到Media Type为application/json、Type为com.jersey.jaxb.Todo、GenericType为com.jersey.jaxb.Todo的MessageBodyWriter。


1
这真的帮助我解决了问题,如果您不使用Maven。 - Lakshmi
7个回答

54

你有 jackson-jaxrs-json-provider 这个依赖,这是一个好的开始...

但是...

该工件仍然依赖于 Jackson 本身,其中包括所有这些 artifact。

enter image description here

这就是为什么我们使用 Maven[1] (这样我们就不必担心这种事情了 :-)),所以去找到它们。

然后只需将包添加到 web.xml 中,它应该就可以正常工作了。

<param-name>jersey.config.server.provider.packages</param-name>
<param-value>
    com.jersey.jaxb,
    com.fasterxml.jackson.jaxrs.json
</param-value>

1. Maven依赖

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

或者使用以下的Jersey“包装器”来处理上述依赖关系。它会注册Jackson提供程序(因此我们不需要像上面那样显式注册),以及Jackson异常映射器,并且从2.17版本开始,提供对实体数据过滤的支持。

<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-json-jackson</artifactId>
    <version>${jersey2.version}</version>
</dependency>

注意: 上述依赖项无需注册是因为使用了Jersey的自动发现功能。如果由于某种原因禁用了自动发现,您需要显式注册JacksonFeature


我目前没有使用Maven。因此,我应该先下载所有这些JAR文件并将其添加到我的应用程序中,然后将您上面提到的那行代码添加到我的web.xml文件中。 - Raj Hassani
这是下载页面(http://wiki.fasterxml.com/JacksonDownload)。我不需要使用截图中列出的最后一个.jar文件。对我有效! - user3063836
算了,我确实需要“jackson-module-jaxb-annotations-2.2.3.jar”将JSON转换为XML。 - user3063836
这将解决问题:<dependency> <groupId>org.glassfish.jersey.media</groupId> <artifactId>jersey-media-json-jackson</artifactId> <version>${jersey.version}</version> </dependency> - bkomac
提供程序包 com.jersey.jaxb 似乎有误,我认为它不存在。 - Johannes Jander
嗨,在Weblogic上 - 不需要调整任何web.xml参数。有了依赖项: jackson-jaxrs-json-provider你提到的,Weblogic 12.2.1.2停止抱怨他不知道如何将响应呈现为JSON。在Wildfly上,不需要这样的依赖关系。在这种情况下,我正在尝试简单地返回一个LIst<String>。您对此有什么见解吗? - 99Sono

17

解决方法可能是确保模型类具有无参构造函数。

并在您的pom.XML中添加此依赖项:

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

9

我遇到了同样的问题,我通过向类中添加一个空构造函数来解决它。

public SandBoxClass(){} //-> solved the issue**

public SandBoxClass(Integer arg1, Integer arg2) {
        this.arg1=arg1;
        this.arg2=arg2;
}

3
如果您已经在pom.xml中添加了jersey-media-moxy依赖,请确保您的实体类具有默认构造函数。 当我在模型类中引入参数化构造函数时,我遇到了这个问题。再次添加默认构造函数对我有用。

对于那些像我一样使用 lombok 并且使用 @Builder 的人,你需要添加这些注释:@NoArgsConstructor@AllArgsConstructor - Vielinko

1
关于我,注册JacksonFeature对我有帮助:
public class App extends ResourceConfig {
   public App() {
       packages("info.ernestas.simplerest");
       register(new JacksonFeature()); // This magical line helped
   }
}

0

0
  1. 更新Jax-RS 2.0和Jersey 2.5.1(仅限JAX-RS-RI)库。
  2. 返回Bean对象(todo),而不是响应,因为在自动生成json或xml时,响应会创建问题。

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