找不到 Java 类型 myPackage.B 类和 MIME 媒体类型 application/octet-stream 的消息正文编写器

Posted

技术标签:

【中文标题】找不到 Java 类型 myPackage.B 类和 MIME 媒体类型 application/octet-stream 的消息正文编写器【英文标题】:A message body writer for Java type, class myPackage.B, and MIME media type, application/octet-stream, was not found 【发布时间】:2011-12-11 13:51:24 【问题描述】:

我是 RESTful webservices 的新手,正试图从独立的客户端应用程序更新我的 @OneToMany 关系,但我无法做到这一点。我正在使用 Glassfish 3.1.1 附带的 JAX-RS 的 Jersey 实现。

我有一个类A,它与类B@OneToMany 关系。

MyRestClient 是我的独立客户端,它正在调用已部署在 Glassfish 3.1.1 上的 RESTful Web 服务。

MyRestClient.java

public class MyRestClient 
    public static void main(String[] args)     
        Client client = Client.create();        
        WebResource resource = client.resource("http://localhost:8080/myapp/rest/a/update/123");    
        B b1 = new B("debris");     
        ClientResponse response = resource.put(ClientResponse.class, b1);
        System.out.println(response.getEntity(A.class).getTitle() + " has " + response.getEntity(A.class).getBList().size() + " Bs.");
    

AResource 是一个 EJB 会话 bean,我将其用作 RESTful Web 服务。

AResource.java

@Stateless
@Path("/a")
public class AResource 

    @EJB
    private AManager aManager;

    @PUT
    @Consumes(MediaType.APPLICATION_XML)
    @Produces(MediaType.APPLICATION_XML)
    @Path("/update/id")
    public Response updateA(B b, @PathParam("id") int id) 
        A a = aManager.findAById(id);
        a.addB(b);
        return Response.status(Status.OK).entity(a).build();
    

当我运行客户端时,我收到以下错误消息: com.sun.jersey.api.client.ClientHandlerException:

以下是我的独立客户端应用程序中的域对象,它正在调用 AResource EJB 会话 bean,我将其用作 RESTful Web 服务。

A.java

@XmlRootElement
public class A implements Serializable 

    private List<B> bList = new ArrayList<B>();
    public List<B> getBList() 
        return bList;
    
    //remaining code


B.java

public class B implements Serializable 

    private String text;
    private A a;    


    @XmlTransient
    public A getA() 
        return a;
    

    public void afterUnmarshal(Unmarshaller u, Object parent) 
        this.a = (A) parent;
    
    //remaining code


有人能帮我理解为什么会发生这种情况以及我应该如何解决这个问题吗?

【问题讨论】:

【参考方案1】:

在您的客户端代码中,您没有指定要发送的数据的内容类型 - 因此 Jersey 无法找到正确的 MessageBodyWritter 来序列化 b1 对象。

修改你的main方法的最后一行如下:

ClientResponse response = resource.type(MediaType.APPLICATION_XML).put(ClientResponse.class, b1);

并在服务器端和客户端向 B 类添加 @XmlRootElement 注解。

【讨论】:

我做了建议的更改,但它仍然给我同样的错误。 哦,你在 B 类上缺少 @XmlRootElement 注释 - 也添加它。 这可能是由于服务器上的错误。尝试将响应实体读取为字符串(而不是 A)并将其打印出来以查看从服务器返回的内容。还要检查服务器日志是否有异常。 这是因为泽西岛一旦读取就不会缓存实体。 getEntity() 读取响应流并将其传递给消息正文阅读器进行处理,一旦处理,它会关闭流并返回它 - 对 getEntity() 的后续调用将失败,导致流已被读取并且它不能去回来再读一遍。 我同意这并不明显,应该记录在案 - 我提交了一个错误:java.net/jira/browse/JERSEY-795【参考方案2】:

在您的 POM.xml 中包含此依赖项并运行 Maven -> 更新

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

【讨论】:

这是节省时间的好方法,因为 Jersey API 允许您转换从 Web 服务对象接收到的字符串【参考方案3】:

您需要从 B.class 中指定 @Provider@Produces(MediaType.APPLICATION_XML) 将您的 MessageBodyWriter&lt;B.class&gt; 的包添加到您的 /WEB_INF/web.xml 为:

<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>
your.providers.package
</param-value>
</init-param>

【讨论】:

我无法尝试@Provider,因为我目前无法访问该代码。会让你知道。谢谢。【参考方案4】:

你必须做两件事来消除这个错误。

    模型中的@xmlElement 映射

    客户端:

    response = resource.type(MediaType.APPLICATION_XML).put(ClientResponse.class, b1); //consume

    response = resource.accept(MediaType.APPLICATION_XML).put(ClientResponse.class, b1); //produce

【讨论】:

***.com/questions/17342218/… ..你能解决这个问题吗??【参考方案5】:

添加参考:

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

只要在创建客户端时添加 clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, true); 就可以解决我的问题:

ClientConfig clientConfig = new DefaultClientConfig();
clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, true);
Client client = Client.create(clientConfig);

【讨论】:

【参考方案6】:

如果您最近升级了 Ant,也会发生这种情况。我在一个项目上使用Ant 1.8.4,将Ant升级到1.9.4,在使用Ant构建fat jar时开始出现这个错误。

对我来说,解决方案是将命令行和 Eclipse using the process detailed here 降级回 Ant 1.8.4@

【讨论】:

【参考方案7】:

我在get方法中遇到了同样的问题我为@get方法返回了一个“int”奇怪的是,当我将返回类型更改为String时,错误消失了。试一试,如果有人知道背后的逻辑它请分享它

【讨论】:

我认为将返回类型更改为 String 是不可接受的解决方案【参考方案8】:

这解决了我的问题。

http://www.markhneedham.com/blog/2012/11/28/jersey-com-sun-jersey-api-client-clienthandlerexception-a-message-body-reader-for-java-class-and-mime-media-type-applicationjson-was-not-found/

在您的 POM.xml 中包含以下依赖项并运行 Maven -> 更新也解决了我的问题。

<dependency>
    <groupId>com.sun.jersey</groupId>
    <artifactId>jersey-json</artifactId>
    <version>1.19.1</version>
</dependency>
<dependency>
   <groupId>com.owlike</groupId>
   <artifactId>genson</artifactId>
   <version>0.99</version>
</dependency>

【讨论】:

【参考方案9】:

如果您缺少实体的空公共构造函数(可能是 JSON、XML 等),也会发生这种情况..

【讨论】:

【参考方案10】:

确保所有这些库都在您的类路径中:

compile(group: 'com.sun.jersey', name: 'jersey-core',        version: '1.19.4') 
compile(group: 'com.sun.jersey', name: 'jersey-server',      version: '1.19.4') 
compile(group: 'com.sun.jersey', name: 'jersey-servlet',     version: '1.19.4')
compile(group: 'com.sun.jersey', name: 'jersey-json',        version: '1.19.4')
compile(group: 'com.sun.jersey', name: 'jersey-client',      version: '1.19.4')
compile(group: 'javax.ws.rs', name: 'jsr311-api', version: '1.1.1')
compile(group: 'org.codehaus.jackson', name: 'jackson-core-asl', version: '1.9.2')
compile(group: 'org.codehaus.jackson', name: 'jackson-mapper-asl', version: '1.9.2')
compile(group: 'org.codehaus.jackson', name: 'jackson-core-asl',   version: '1.9.2')
compile(group: 'org.codehaus.jackson', name: 'jackson-jaxrs',      version: '1.9.2')
compile(group: 'org.codehaus.jackson', name: 'jackson-xc',         version: '1.9.2')

将“Pojo Mapping”和“Jackson Provider”添加到 jersey 客户端配置中:

ClientConfig clientConfig = new DefaultClientConfig();
clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE);
clientConfig.getClasses().add(JacksonJsonProvider.class);

这解决了我!

ClientResponse response = null;

response = webResource
        .type(MediaType.APPLICATION_JSON)
        .accept(MediaType.APPLICATION_JSON)
        .get(ClientResponse.class);


if (response.getStatus() == Response.Status.OK.getStatusCode()) 

    MyClass myclass = response.getEntity(MyClass.class);
    System.out.println(myclass);

【讨论】:

以上是关于找不到 Java 类型 myPackage.B 类和 MIME 媒体类型 application/octet-stream 的消息正文编写器的主要内容,如果未能解决你的问题,请参考以下文章

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

Spring Arangodb 存储边缘但因 MappingException 失败:找不到类型类 java.lang.Object 的 PersistentEntity

java 主启动类找不到

Error:(4, 25) java: 找不到符号符号:类 xxx位置:程序包 xxx.xxx

字段 vehicleRepository 需要一个找不到的 ..VehicleInterface 类型的 bean

java继承实现的基本原理