泽西岛异常:严重: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 QueryParam
或 HTTP 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
实现自己的MessageBodyReader
和MessageBodyWriter
。
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 的消息正文编写器