严重:找不到 Java 类 java.util.ArrayList 和 MIME 媒体类型 application/json 的消息正文编写器

Posted

技术标签:

【中文标题】严重:找不到 Java 类 java.util.ArrayList 和 MIME 媒体类型 application/json 的消息正文编写器【英文标题】:SEVERE: A message body writer for Java class java.util.ArrayList and MIME media type application/json was not found 【发布时间】:2013-12-05 15:44:32 【问题描述】:

我正在测试 RESTful 服务,执行时出现异常,尽管我的类路径 (WEB-INF/lib) 中有以下 jar,但我没有使用 Maven,并且我的 JDK 版本是 1.5。有关此问题的其他问题无助于解决问题。

代码sn-p

@GET
@Produces("application/json")    
//@Produces(MediaType.APPLICATION_JSON) tried this, didn't work either
public List<Emp> getEmployees()         
    List<Emp> empList = myDAO.getAllEmployees();
    log.info("size   " + empList.size());
    return empList;


@XmlRootElement
public class Emp 
......

web.xml

<servlet>
    <servlet-name>Jersey Web Application</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>test.employees</param-value>
    </init-param>
    <init-param>
        <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
        <param-value>true</param-value>
    </init-param>
</servlet>

 <servlet-mapping>
    <servlet-name>Jersey Web Application</servlet-name>
    <url-pattern>/rest/*</url-pattern>
</servlet-mapping>

罐子列表

jersey-server-1.2.jar
jersey-core-1.2.jar
jsr311-api-1.1.jar
asm-3.1.jar
jaxb-api-2.0.jar
jaxb-impl-2.0.jar
jackson-xc-1.2.0.jar
jackson-jaxrs-1.2.0.jar
jackson-mapper-asl-1.2.0.jar
jackson-core-asl-1.2.0.jar
jettison-1.2.jar
jersey-client-1.2.jar
jersey-servlet-1.10.jar
jersey-json-1.8.jar

异常堆栈

 SEVERE: A message body writer for Java class java.util.ArrayList,
 and Java type java.util.List<test.Emp>, 
 and MIME media type application/json was not found
Nov 21, 2013 11:47:26 AM com.sun.jersey.spi.container.ContainerResponse traceException
SEVERE: Mapped exception to response: 500 (Internal Server Error)

javax.ws.rs.WebApplicationException
    at javax.ws.rs.WebApplicationException.<init>(WebApplicationException.java:97)
    at javax.ws.rs.WebApplicationException.<init>(WebApplicationException.java:55)
    at com.sun.jersey.spi.container.ContainerResponse.write(ContainerResponse.java:267)
    at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1035)
    at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:947)
    at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:939)
    at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:399)
    at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:478)
    at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:663)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:856)
    at com.evermind.server.http.ServletRequestDispatcher.invoke(ServletRequestDispatcher.java:719)
    at com.evermind.server.http.ServletRequestDispatcher.forwardInternal(ServletRequestDispatcher.java:376)
    at com.evermind.server.http.HttpRequestHandler.doProcessRequest(HttpRequestHandler.java:870)
    at com.evermind.server.http.HttpRequestHandler.processRequest(HttpRequestHandler.java:451)
    at com.evermind.server.http.HttpRequestHandler.serveOneRequest(HttpRequestHandler.java:218)
    at com.evermind.server.http.HttpRequestHandler.run(HttpRequestHandler.java:119)
    at com.evermind.server.http.HttpRequestHandler.run(HttpRequestHandler.java:112)
    at oracle.oc4j.network.ServerSocketReadHandler$SafeRunnable.run(ServerSocketReadHandler.java:260)
    at oracle.oc4j.network.ServerSocketAcceptHandler.procClientSocket(ServerSocketAcceptHandler.java:230)
    at oracle.oc4j.network.ServerSocketAcceptHandler.access$800(ServerSocketAcceptHandler.java:33)
    at oracle.oc4j.network.ServerSocketAcceptHandler$AcceptHandlerHorse.run(ServerSocketAcceptHandler.java:831)
    at com.evermind.util.ReleasableResourcePooledExecutor$MyWorker.run(ReleasableResourcePooledExecutor.java:303)
    at java.lang.Thread.run(Thread.java:595)

我该如何解决这个问题?

【问题讨论】:

请将球衣相关的 jar 文件更新到 1.17 版本。从这里获取捆绑包jersey.java.net/download.html @mallim jersey bundle 1.17JDK1.5 兼容吗? 参考[此链接][1],其中解释了类似类型问题的解决方案。 [1]:***.com/a/13439840/4469988 【参考方案1】:

确保您的项目中没有多个 Jersey 版本。从您提供的列表中,有来自 3 个不同版本(1.2、1.10、1.8)的模块。对于某些模块,Jersey 会检查模块的版本是否与核心的版本相同。如果不是,则模块的提供者(例如 MessageBodyReaders、MessageBodyWriters)未在运行时中注册。这可能是您的设置中的问题 - json vs core(1.8 vs 1.2)。

【讨论】:

Michal 关于您提到的最后一个 pont,即我尝试使用 json jersey-json 1.2jersey-core-1.2,但问题仍然存在。我需要尝试您的第一点,但是我可以找到 jersey-servlet 的 1.2 版本。我从早上开始就一直在尝试解决这个问题,但是没有成功。 Michal 能否请您建议在 JDK1.5 上运行所需的所有 jar 的正确版本是什么?谢谢 1.2 中没有jersey-servlet(这个模块在~1.9 已经引入)。所有功能都应该在jersey-server 中。此外,我认为 POJO 映射功能 (com.sun.jersey.api.json.POJOMappingFeature) 的支持不在 1.2 中,这可能意味着自定义 json 解析器无法处理 List&lt;Emp&gt;。你能尝试至少切换到 1.9 吗? 所以你的意思是说我应该试试1.9 jersey-server 而不是1.2?如果是这样,我应该使用除jersey-servlet 之外的所有1.9 版本? 我的意思是对所有 Jersey 模块使用 1.9(+ 你将能够将 Jackson 用于 JavaJSON,它应该能够处理 List)。 @omega 的建议也可能对某些 JSON 解析器有效。【参考方案2】:

您不能将响应Xml 定义为List&lt;Emp&gt;,因为JAXB 无法识别@XmlRootElement 而不是java.util.Listjava.util.ArrayList 类定义。

理想情况下,您的子元素集合应该有一个父/根元素。

再创建一个类为Employees 以包含Emp 对象的集合,如下所示并尝试一下。

@GET
@Produces("application/json")    
public Employees getEmployees()         
    List<Emp> empList = myDAO.getAllEmployees();
    log.info("size   " + empList.size());
    Employees employees = new Employees();
    employees.setEmployeeList(empList);

    return employees;


@XmlRootElement(name = "Employees")
public class Employees 

    List<Emp> employeeList;

    //setters and getters goes here


@XmlRootElement()
class Emp 
   //fields here

请尝试这种方法,它会起作用。

【讨论】:

我已经尝试过你的方法,但是我仍然有同样的错误。与我已有的相同设置和相同版本的 jars。【参考方案3】:

问题可能在于您尝试返回结果的方式。我也看到其他人也用这种方式编写他们的服务层代码,但 Jersey 提供了一种简洁的方式,它将支持 JSON、XML 和 HTML 输出,您只需要使用 @Produces 指定这些输出注解。我就是这样做的:

import javax.ws.rs.GET;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.GenericEntity;
import javax.ws.rs.core.Response;

@GET
@Produces( MediaType.APPLICATION_JSON )
public Response getEmployees()
        
    List< Emp >                  matched;
    GenericEntity< List< Emp > > entity;

    matched = myDAO.getAllEmployees();
    entity  = new GenericEntity< List< Emp > >( matched )  ;

    return Response.ok( entity ).build();

我正在使用以下 Jersey 库:

jersey-core-1.8.jar jersey-json-1.8.jar jersey-server-1.8.jar

【讨论】:

【参考方案4】:

将此添加到您的 pom.xml 中。解决了我的问题。

        <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>

【讨论】:

【参考方案5】:

在要作为输出传递的类上指定@XmlRootElement(name = "yourclass")。当我得到这个异常时,这已经解决了我的问题。

【讨论】:

我不相信这可能会解决问题,因为注释与 JSON 而不是 XML 相关,但它有效!你让我很开心,非常感谢 同上!他说了什么! ^【参考方案6】:

我遇到了同样的问题。

问题是它知道如何使用注释@XmlRootElement 将其转换为xml,但它不知道如何将其转换为JSON。

因此,为了使其将所有内容转换为具有相同 xml 注释的 JSON(即 @XmlRootElement),我们可以添加

jersey-media-moxy-&lt;whatever version&gt;.jar

或者对于 maven 用户

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

它还应该有一个无参数构造函数

【讨论】:

【参考方案7】:

您必须在球衣的servlet container 中声明参数如下:

'com.sun.jersey.api.json.POJOMappingFeature' like this: 
 <servlet>
    <servlet-name>myServices</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>services</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>

【讨论】:

【参考方案8】:

交叉检查你的 pojo 类可能没有完成 JAXBinding 如果没有完成用 @XmlRootElement 标记你的 pojo

【讨论】:

【参考方案9】:

我有同样的问题。然后我解决了。

<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>aaa</groupId>
    <artifactId>aaa</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <build>
        <sourceDirectory>src</sourceDirectory>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.0</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>

    </build>
    <dependencies>
        <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>
        <dependency>
            <groupId>org.jsoup</groupId>
            <artifactId>jsoup</artifactId>
            <version>1.7.3</version>
        </dependency>
        <dependency>
            <groupId>jakarta.ws.rs</groupId>
            <artifactId>jakarta.ws.rs-api</artifactId>
            <version>2.1.6</version>
        </dependency>
        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-bundle</artifactId>
            <version>1.19.4</version>
        </dependency>
    </dependencies>
</project>

我的方法在这里。

public static void postData() 
    Staff staff = new Staff();
    staff.setStaffname("Celal");                staff.setStafflastname("Aygar");
    staff.setEmail("celal.aygar@gmail.com");    staff.setGender("Male");
    staff.setCity("DENIZLI");
    String uri = "http://localhost:8185/staff";
    ClientConfig clientConfig = new DefaultClientConfig();
    clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, true);
    Client client = Client.create(clientConfig);
    WebResource resource = client.resource(uri);
    try 
        ClientResponse response = resource.type(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)
                .post(ClientResponse.class, staff);
        if (response.getStatus() == 200) System.out.println("Staff detail : " + response.getEntity(Staff.class));
     catch (Exception e)  System.out.println("Exception is:" + e.getMessage()); 

我的实体在这里。

@XmlRootElement()
public class Staff 
    private Long staffid;

    private String staffname;
    private String stafflastname;
    private String gender;
    private String email;
    private String city;

    //getter setter toString


【讨论】:

以上是关于严重:找不到 Java 类 java.util.ArrayList 和 MIME 媒体类型 application/json 的消息正文编写器的主要内容,如果未能解决你的问题,请参考以下文章

解决java.lang.IllegalArgumentException: No converter found for return value of type: class java.util.A

idea找不到监听器类。导入了web包的

java基础之自定义异常类及throw和throws的区别

java 主启动类找不到

java找不到或无法加载主类

使用java的jar包默认类提示找不到符号