【问题标题】:A message body writer for Java class java.util.ArrayList and MIME media type application/json was not found找不到 Java 类 java.util.ArrayList 和 MIME 媒体类型 application/json 的消息正文编写器
【发布时间】:2018-04-20 01:35:14
【问题描述】:

我正在尝试让 Web 服务正常工作,该服务返回 JSON(在 Tomcat 上带有球衣实现的 JAX-RS)。但是,我收到以下异常。我在这里查看了类似的问题,但没有一个解决方案对我有用,而且已经超过半天了:(

07-Nov-2017 20:47:17.109 SEVERE [http-nio-8080-exec-2] com.sun.jersey.spi.container.ContainerResponse.write A message body writer for Java class java.util.ArrayList, and Java type java.util.List<org.saurabh.Message>, and MIME media type application/json was not found.
The registered message body writers compatible with the MIME media type are:
application/json ->
  com.sun.jersey.json.impl.provider.entity.JSONJAXBElementProvider$App
  com.sun.jersey.json.impl.provider.entity.JSONRootElementProvider$App
  com.sun.jersey.json.impl.provider.entity.JSONListElementProvider$App
*/* ->
  com.sun.jersey.core.impl.provider.entity.FormProvider
  com.sun.jersey.core.impl.provider.entity.StringProvider
  com.sun.jersey.core.impl.provider.entity.ByteArrayProvider
  com.sun.jersey.core.impl.provider.entity.FileProvider
  com.sun.jersey.core.impl.provider.entity.InputStreamProvider
  com.sun.jersey.core.impl.provider.entity.DataSourceProvider
  com.sun.jersey.core.impl.provider.entity.XMLJAXBElementProvider$General
  com.sun.jersey.core.impl.provider.entity.ReaderProvider
  com.sun.jersey.core.impl.provider.entity.DocumentProvider
  com.sun.jersey.core.impl.provider.entity.StreamingOutputProvider
  com.sun.jersey.core.impl.provider.entity.SourceProvider$SourceWriter
  com.sun.jersey.server.impl.template.ViewableMessageBodyWriter
  com.sun.jersey.json.impl.provider.entity.JSONJAXBElementProvider$General
  com.sun.jersey.core.impl.provider.entity.XMLRootElementProvider$General
  com.sun.jersey.core.impl.provider.entity.XMLListElementProvider$General
  com.sun.jersey.json.impl.provider.entity.JSONRootElementProvider$General
  com.sun.jersey.json.impl.provider.entity.JSONListElementProvider$General

07-Nov-2017 20:47:17.110 SEVERE [http-nio-8080-exec-2] com.sun.jersey.spi.container.ContainerResponse.logException Mapped exception to response: 500 (Internal Server Error)
 javax.ws.rs.WebApplicationException: com.sun.jersey.api.MessageException: A message body writer for Java class java.util.ArrayList, and Java type java.util.List<org.saurabh.Message>, and MIME media type application/json was not found.

    at com.sun.jersey.spi.container.ContainerResponse.write(ContainerResponse.java:284)
    at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1510)
    at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1419)
    at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1409)
    at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:409)
    at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:558)
    at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:733)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:475)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:651)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:500)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:754)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1376)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)
Caused by: com.sun.jersey.api.MessageException: A message body writer for Java class java.util.ArrayList, and Java type java.util.List<org.saurabh.Message>, and MIME media type application/json was not found.

    ... 30 more

资源类如下:

package org.saurabh;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.util.ArrayList;
import java.util.List;

@Path("/messages")
public class MessageResource {

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public List<Message> getMessages() {
        List<Message> messages = new ArrayList<Message>();
        messages.add(new Message(1L, "Hello India", "Saurabh"));
        messages.add(new Message(2L, "Hello World", "Saurabh"));
        return messages;
    }
}

模型类如下。我已经用 @XmlRootElement 注释对其进行了注释(如其他一些答案中所建议的那样),并且有一个无参数构造函数。

package org.saurabh;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Message {

    private long   id;
    private String message;
    private String user;

    public Message() {
    }

    public Message(long id, String message, String user) {
        this.id = id;
        this.message = message;
        this.user = user;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public String getUser() {
        return user;
    }

    public void setUser(String user) {
        this.user = user;
    }
}

pom.xml 文件:

<?xml version="1.0" encoding="UTF-8"?>
<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>org.saurabh</groupId>
    <artifactId>JAX-RS-Rest-Tutorial</artifactId>
    <version>1.0-SNAPSHOT</version>

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

        <dependency>
            <groupId>org.glassfish.jersey.media</groupId>
            <artifactId>jersey-media-moxy</artifactId>
            <version>2.6</version>
        </dependency>
    </dependencies>
</project>

web.xml 文件:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

    <servlet>
        <servlet-name>Example API</servlet-name>
        <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>

        <init-param>
            <param-name>com.sun.jersey.spi.container.servlet.ServletContainer</param-name>
            <param-value>com.example.jersey</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>Example API</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>

</web-app>

请注意,如果我将返回类型更改为 application/xml,那么它可以正常工作。只是对于JSON,它一直在给出这个错误。

@GET
@Produces(MediaType.APPLICATION_XML)
public List<Message> getMessages() {
    // works fine
}

【问题讨论】:

  • @Jerry06:答案是使用Jackson,然后扩展配置类。我认为必须有开箱即用的方法来处理这个问题。
  • XmlRootElement 应该不是必需的。上次我使用它时,它与 JAX-WS 一起用于 SOAP Web 服务。
  • @LppEdd 删除 XmlRootElement 也无济于事:(
  • @OneMoreError 看看这里mkyong.com/webservices/jax-rs/json-example-with-jersey-jackson 无论如何,我强烈建议升级到像 Spring 这样更易于理解的东西(参见 @RestController)。

标签: java json jersey jax-rs moxy


【解决方案1】:

您尝试使用的 MOXy 依赖项适用于 Jersey 2.x。您需要 1.x 版本的,因为这就是您正在使用的

<dependency>
    <groupId>com.sun.jersey</groupId>
    <artifactId>jersey-json</artifactId>
    <version>1.18.3</version>
</dependency>

【讨论】:

    猜你喜欢
    • 2016-10-01
    • 2013-12-05
    • 2018-01-26
    • 2012-08-16
    • 2013-03-15
    • 2011-12-11
    • 2014-03-20
    • 2016-06-14
    • 2013-12-15
    相关资源
    最近更新 更多