泽西岛异常:严重:Java 类的消息正文阅读器

Posted

技术标签:

【中文标题】泽西岛异常:严重:Java 类的消息正文阅读器【英文标题】:Jersey Exception : SEVERE: A message body reader for Java class 【发布时间】:2012-01-25 13:16:54 【问题描述】:

我有一个基于 Jersey 的 Rest WS,它输出 JSON。我正在实现一个 Jersey 客户端来调用 WS 并使用 JSON 响应。我的客户端代码如下

WebResource r = restClient.resource(UriBuilder.fromUri("http://localhost/").port(8080).build()); String resp = r.path("/user").accept(MediaType.APPLICATION_JSON).get(String.class); User[] users = r.path("/user").accept(MediaType.APPLICATION_JSON).get(User[].class);

第二行正确输出 JSON 字符串响应,但是将 JSON 编组到 POJO 的第三行没有发生,我得到以下异常堆栈跟踪

严重:Java 类 [Lorg.shoppingsite.model.entity.jpa.User; 和 Java 类型类 [Lorg.shoppingsite.model.entity.jpa.User; 和 MIME 媒体类型 application/json 的消息正文阅读器没有成立 2011 年 12 月 21 日上午 11:32:01 com.sun.jersey.api.client.ClientResponse getEntity SEVERE:与 MIME 媒体类型兼容的注册消息正文阅读器是: */* -> 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.SourceProvider$StreamSourceReader com.sun.jersey.core.impl.provider.entity.SourceProvider$SAXSourceReader com.sun.jersey.core.impl.provider.entity.SourceProvider$DOMSourceReader com.sun.jersey.core.impl.provider.entity.XMLRootElementProvider$General com.sun.jersey.core.impl.provider.entity.XMLListElementProvider$General com.sun.jersey.core.impl.provider.entity.XMLRootObjectProvider$General com.sun.jersey.core.impl.provider.entity.EntityHolderReader

我的请求中有正确​​的 MIME 类型。我的 POJO 已经用 XMLRootElement 进行了注释。我错过了什么。

谢谢

【问题讨论】:

仅供参考...在我的情况下,代码在 IntelliJ 中运行良好,但在打包和部署时失败。我使用带有 jar-with-dependencies 选项的maven-assembly-plugin。我将改用 Jackson ObjectMapper,这是一种解决方法。 @PatS 我面临着类似的问题。代码在使用 Intellij 运行时运行良好,但在打包时抛出相同的错误。与您不同,我无权使用 Jackson ObjectMapper,因为问题在于依赖关系。您找到解决问题的替代方案了吗? @Ajay。我标记的解决方案对我有用。我的猜测是,在您的 IntelliJ 中,您有一些需要的 jar 文件或者是“正确的版本”,并且它是在另一个文件中挑选出来的。这类问题很困难。我建议尝试使用 Shade 插件(请参阅 maven.apache.org/plugins/maven-shade-plugin)并启用调试以查看哪些类是重复的。在 IntelliJ 之外运行时,代码很可能引入了错误版本的文件。 【参考方案1】:

Q) 代码在 Intellj 中运行良好,但在命令行中失败。

Sol) 将 jersey 的依赖项添加为直接依赖项而不是临时依赖项。

推理:因为它在 IntelliJ 上运行良好,所以依赖项配置正确。

    通过以下方式之一获取所需的依赖项:

      检查 IntelliJ 运行命令。 ***-link 列出来自 maven mvn dependency:tree 的依赖项

    现在,明确添加那些有问题的球衣依赖项。

【讨论】:

【参考方案2】:

对于 Python 和 Swagger 示例:

import requests
base_url = 'https://petstore.swagger.io/v2'
def store_order(uid):
    api_url = f"base_url/store/order"
    api_data = 
        'id':uid,
        "petId": 0,
        "quantity": 0,
        "shipDate": "2020-04-08T07:56:05.832Z",
        "status": "placed",
        "complete": "true"
        
    # is a kind of magic..
    r = requests.post(api_url, json=api_data)
    return r
print(store_order(0).content)    

最重要的 MIME 类型字符串: r = requests.post(api_url, json=api_data)

【讨论】:

【参考方案3】:

如果您正在构建 uberjar 或“shaded jar”,请确保您的 meta inf 服务文件已合并。 (这在 dropwizard 项目中多次咬我。)

如果您使用的是 gradle shadowJar 插件,您想在您的shadowJar 目标中调用mergeServiceFiles():https://github.com/johnrengelman/shadow#merging-service-files

不确定 maven 或其他构建系统的类似命令是什么。

【讨论】:

为 Maven 添加一个转换器:ServicesResourceTransformer。这实际上让我通过了这个发布的错误消息。但是,它没有抱怨,而是我的 .getEntity() 调用挂起。关于 json 的一些事情,因为如果我要求一个 String 实体,它不会挂起。 maven.apache.org/plugins/maven-shade-plugin/examples/… 谢谢,使用ServicesResourceTransformer 为我解决了这个问题com.sun.jersey.api.client.ClientHandlerException: A message body reader for Java class org.x.y , and Java type class org.x.y and MIME media type application/xml; charset=UTF-8 was not found(注意我的没有抱怨json,但可能仍然适用)(在我的项目中添加更多依赖项后出现问题) 【参考方案4】:

我能够通过为 jersey-json 添加 maven 依赖项来解决此问题。

【讨论】:

这是正确的,有关添加 maven 依赖项的更详细步骤,请参阅this answer below。 对于 IntelliJ,在项目结构中添加来自 maven 的 jersey-json 是不够的。将条目添加到 pom.xml 解决了它。 我面临同样的问题,我也有 sdded jersey-json。但它不能解决问题。 这太糟糕了,@AmitGupta。你做了什么? 这个问题是因为出现错误时的 html 响应。【参考方案5】:

我知道这篇文章很旧,你很久以前就知道了,但只是为了拯救那些会在一段时间内阅读这篇文章的人。

您可能忘记为要传递到端点的实体添加注释,因此 Jersey 不知道如何处理它接收到的 POJO。 用这样的东西注释 pojo:

@XmlRootElement(name = "someName")

【讨论】:

即使在将 jersey-json 添加到 pom.xml 之后,这也是必需的。 +1【参考方案6】:

尝试添加:

<dependency>
    <groupId>com.owlike</groupId>
    <artifactId>genson</artifactId>
    <version>1.4</version>
</dependency>

如果您使用带有消息正文的HTTP GET,也可能会出现此问题,因此在这种情况下添加 jersey-json lib、@XmlRootElement 或修改 web.xml 将无济于事。您应该使用 URL QueryParamHTTP POST

【讨论】:

【参考方案7】:

只需在课程开始前在您的 POJO 中添加以下行,您的问题就解决了。 @Produces("应用程序/json") @XmlRootElement 查看示例 导入 javax.ws.rs.Produces; 导入 javax.xml.bind.annotation.XmlRootElement;

 /**
 * @author manoj.kumar
 * @email kumarmanoj.mtech@gmail.com
 */
 @Produces("application/json")
 @XmlRootElement  
 public class User 

 private String username;
 private String password;
 private String email;
 public String getUsername() 
 return username;
 
 public void setUsername(String username) 
     this.username = username;
 
 public String getPassword() 
     return password;
 
 public void setPassword(String password) 
     this.password = password;
 
 public String getEmail() 
    return email;
 
 public void setEmail(String email) 
    this.email = email;
 


add below lines inside of your web.xml
<init-param>
    <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
    <param-value>true</param-value>
</init-param>  
Now recompile your webservice everything would work!!!

【讨论】:

xmlrootelement 与发送 JSON 对象有什么关系?【参考方案8】:

我们还决定使用球衣作为解决方案。但是由于我们在大多数情况下都使用 org.JSON,所以这种依赖是不必要的,我们感觉不好。

因此我们使用 String 表示来获取 org.JSON 对象,而不是

JSONObject output = response.getEntity(JSONObject.class); 

我们现在这样使用它:

JSONObject output = new JSONObject(response.getEntity(String.class)); 

其中 JSONObject 来自 org.JSON 并且可以从以下位置更改导入:

-import org.codehaus.jettison.json.JSONArray;
-import org.codehaus.jettison.json.JSONException;
-import org.codehaus.jettison.json.JSONObject;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;

【讨论】:

【参考方案9】:

有些人可能会疑惑为什么添加 jersey-json jar 不能解决这个问题。我发现这个 jar 必须比 jersey-json-1.7.jar 更新(1.7.0 不起作用,但 1.7.1 可以正常工作。)。希望这可以帮助

【讨论】:

这是对问题的评论或尝试回答;有空的时候请把它放在那里。【参考方案10】:

我的情况类似。我在关键时刻遇到了这个错误,我不记得我以前是如何解决它的,我做了很多次。经过数小时的艰苦检查,我已经解决并重现了错误,并确保解决这种情况的方法有多简单。

好的 - 解决方案:删除(或更正)对主项目的属性文件所做的任何新更改。

是的,就是这样。事实上,我的项目是一个多模块的大型项目,你知道没有正确的依赖关系是一种罕见的情况,因为它经常从 git(RAC 也是)中获取。我的项目从一个属性文件中获取几乎所有可配置的东西,该文件对于大约 15 个左右的模块(子项目)来说是通用的,它们之间有大量的内部依赖关系。 jersey-json 的依赖项始终存在于我合并的父 pom 中。 XML 注释不是问题,因为项目在修改它们后运行了大约 100 次。这里的一些解决方案指向 web.xml 和 POJOMappingFeature 之类的东西。在我的例子中,我什至没有在这个版本中接触过 webapp 模块。所以无论如何,这个解决方案对我有用,我花时间在 SO 中记录它,以防万一我碰巧陷入这个错误,我不必浪费我的困倦之夜。 (当然,你也一样)

【讨论】:

【参考方案11】:

要让它工作,你只需要两件事。检查您是否丢失:

    首先,您需要为您的对象类/实体添加 @XmlRootElement 注释。

    如果您丢失,您需要为 jersey-json 添加依赖项。供您参考,我将此依赖项添加到我的 pom.xml 中。

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

【讨论】:

在我的情况下,只需添加 jersey-json 依赖项就足够了。 干得好!我们一直在追逐这个罐子......谢谢! JSON 对象需要 @XmlBlahBlah 似乎很奇怪,对我没有帮助。 我必须同时添加注释和 maven 依赖项 您可能还需要使用 maven shade 插件来合并 META-INF/services/javax.ws.rs.ext.MessageBodyWriter 和 META-INF/services/javax.ws.rs.ext.MessageBodyReader jersey-core 和 jersey-json 库,请参考***.com/a/13279921/1699468【参考方案12】:

就我而言,我使用的是 POJO。而且我忘记将 POJOMappingFeature 配置为 true。 Maycon 在早期的回答中指出了这一点。但是有些人可能无法在 web.xml 中正确配置它,这是我的示例。

<servlet>
    <servlet-name>Jersey Servlet</servlet-name>
    <servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
    <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>

【讨论】:

或在代码中:clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE);【参考方案13】:

只需检查您是否在 Eclipse 中运行不同的实例。我退出了所有其他会话,干净的构建解决了问题

【讨论】:

【参考方案14】:

放这个

    <init-param>
        <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
        <param-value>true</param-value>
    </init-param>

【讨论】:

web.xml。见mkyong.com/webservices/jax-rs/json-example-with-jersey-jackson 这个建议以及添加 jersey-json 依赖项解决了我的问题,我得到了来自服务器的有效响应【参考方案15】:

您需要为您的班级Lorg.shoppingsite.model.entity.jpa.User 实现自己的MessageBodyReaderMessageBodyWriter

package javax.ws.rs.ext;

import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;

public interface MessageBodyReader<T extends Object> 

    public boolean isReadable(Class<?> type, 
        Type genericType, 
        Annotation[] annotations, 
        MediaType mediaType);

    public T readFrom(Class<T> type, 
        Type genericType, 
        Annotation[] annotations, 
        MediaType mediaType, 
        MultivaluedMap<String, String> httpHeaders, 
        InputStream entityStream) throws IOException, WebApplicationException;


package javax.ws.rs.ext;

import java.io.IOException;
import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;

public interface MessageBodyWriter<T extends Object> 

    public boolean isWriteable(Class<?> type, 
        Type genericType, 
        Annotation[] annotations, 
        MediaType mediaType);

    public long getSize(T t, 
        Class<?> type, 
        Type genericType, 
        Annotation[] annotations, 
        MediaType mediaType);

    public void writeTo(T t, 
        Class<?> type, 
        Type genericType, 
        Annotation[] annotations, 
        MediaType mediaType, 
        MultivaluedMap<String, Object> httpHeaders, 
        OutputStream entityStream) throws IOException, WebApplicationException;

【讨论】:

我认为你的方法不是常用的方法。通常,将 JSON 映射到 POJO 可以使用 JAXB,而无需创建自己的 messageBodyReader,因为 JSON 的消息阅读器已经存在。见 VDev 的回答。

以上是关于泽西岛异常:严重:Java 类的消息正文阅读器的主要内容,如果未能解决你的问题,请参考以下文章

未找到 Java 类型和 MIME 媒体类型 application/json;charset=utf-8 的消息正文阅读器

未找到 Java 类型、类 org.json.JSONObject.... 和 MIME 媒体类型、application/json 的消息正文阅读器

Java Jersey注册Multipart表单上载文件服务 - 错误:未找到消息正文阅读器

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

java虚拟机规范阅读异常

如何将机器人消息发送到一台服务器中的多个通道(阅读正文以获取更多信息)