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

时间:2011-10-20 07:57:00

标签: web-services rest jersey java-ee-6 jax-rs

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

我的班级A与班级@OneToManyB关系。

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

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:找不到Java类型的邮件正文编写器,类myPackage.B和MIME媒体类型application / octet-stream

以下是我的独立客户端应用程序中的域对象,它正在调用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

}

有人可以帮我理解为什么会这样,以及我该如何解决这个问题?

10 个答案:

答案 0 :(得分:30)

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

修改main方法的最后一行,如下所示:

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

将@XmlRootElement注释添加到服务器端和客户端的B类。

答案 1 :(得分:4)

在POM.xml中包含此依赖项并运行Maven - &gt;更新

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

答案 2 :(得分:2)

您需要指定来自B.class的@Provider @Produces(MediaType.APPLICATION_XML)
MessageBodyWriter<B.class>的包添加到您的/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>

答案 3 :(得分:1)

您必须做两件事才能消除此错误。

  1. 模型中的@xmlElement映射
  2. 客户方:

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

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

答案 4 :(得分:1)

添加对:

的引用
<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);

答案 5 :(得分:0)

如果您最近升级了Ant,也会发生这种情况。我在项目中使用Ant 1.8.4,并将Ant升级到1.9.4,并在使用Ant构建胖罐时开始出现此错误。

我的解决方案是将命令行和Eclipse using the process detailed here

降级回Ant 1.8.4

答案 6 :(得分:0)

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

答案 7 :(得分:0)

这解决了我的问题。

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 - &gt;更新也解决了我的问题。

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

答案 8 :(得分:0)

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

答案 9 :(得分:0)

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

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

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);
}