【问题标题】:Jersey client exception: A message body writer was not found泽西客户端异常:未找到消息正文编写器
【发布时间】:2013-03-23 09:10:44
【问题描述】:

我正在使用 Jersey 客户端访问 PHP Web 服务以实现图像上传功能。我收到以下异常:

Caused by: com.sun.jersey.api.client.ClientHandlerException: 
A message body writer for Java type, class 
com.sun.jersey.multipart.FormDataMultiPart, and MIME media type, 
multipart/form-data, was not found
    at com.sun.jersey.api.client.RequestWriter.writeRequestEntity(RequestWriter.java:288)
    at com.sun.jersey.client.urlconnection.URLConnectionClientHandler._invoke(URLConnectionClientHandler.java:204)
    at com.sun.jersey.client.urlconnection.URLConnectionClientHandler.handle(URLConnectionClientHandler.java:147)
    ... 63 more

这是我正在使用的代码:

WebResource webResource = Client.create().resource(HTTP_REST_URI);
JSONObject jSONObj = webResource.queryParams(queryParams)
      .type(MediaType.MULTIPART_FORM_DATA)
      .post(JSONObject.class, formDataMultiPart);

如何解决这个异常?

【问题讨论】:

  • 您能否再分享一些代码...比如您如何创建表单。在正常情况下您的代码可以工作..

标签: web-services rest jersey


【解决方案1】:

在创建Client 时注册MultiPartWriter 提供程序:

ClientConfig cc = new DefaultClientConfig();
Client client;

cc.getClasses().add(MultiPartWriter.class);
client = Client.create(cc);

如果使用 Maven,这些是您在 pom.xml 中需要的依赖项:

<dependency>
    <groupId>com.sun.jersey</groupId>
    <artifactId>jersey-client</artifactId>
    <version>1.17.1</version>
</dependency>
<dependency>
    <groupId>com.sun.jersey.contribs</groupId>
    <artifactId>jersey-multipart</artifactId>
    <version>1.17.1</version>
</dependency>

【讨论】:

  • 这对我有用!注意client.create(cc); 应该是Client.create(cc); 以避免编译器警告。
  • 谢谢@GáborNagy。我已经在我的答案中修正了大写。
【解决方案2】:

Jersey(服务器或客户端)的提供程序支持将 Java 类型转换为流,反之亦然。 您的代码返回(或接收)一个 Java 对象,并根据对象的类型和您使用的内容类型, Jersey 寻找合适的提供商来进行编组(或解组)。

提供程序实现MessageBodyReaderMessageBodyWriter 接口,并针对每种Java 类型和内容类型 您的应用程序使用的组合必须有一个知道如何处理组合的提供程序。

您收到的消息告诉您,Jersey 找不到知道如何用multipart/form-data mime 类型编组FormDataMultiPart 对象的提供程序。你需要提供一个,如果我没记错的话the default implementation is found in the jersey-multipart.jar and mimepull.jar files

【讨论】:

  • 确保使用jersey-multipart的版本,对应jersey-core的版本。
  • 版本控制的关键可能位于 /META-INF/jersey-module-version 中。每个球衣 jar 文件都有这个文件,我怀疑它们都必须匹配。一旦我得到所有的罐子都是相同的版本。 mimepull.jar 没有这个,但应该匹配 jersey-multipart.jar pom.xml 依赖项中的内容。
【解决方案3】:

我遇到了同样的问题。它通过将 jersey-multipart jar 的 maven 依赖项从 1.0.2 更改为 1.8 版本来解决(在客户端和提供程序端使用相同的依赖项。

             <dependency>
                <groupId>com.sun.jersey.contribs</groupId>
                <artifactId>jersey-multipart</artifactId>
                <version>1.8</version>
             </dependency>

这是我正在使用的完整代码

File file = new File("E:/Goodies/tmp/sparrow.jpg");
byte[] logo = FileUtils.readFileToByteArray(file);

MultiPart multiPart = new MultiPart().bodyPart(new BodyPart(logo, MediaType.APPLICATION_OCTET_STREAM_TYPE));

// POST the request
try{
ClientResponse response = service.type("multipart/mixed").post(ClientResponse.class, multiPart);
System.out.println("Response Status : " + response.getEntity(String.class));
}catch(Exception e){
    e.printStackTrace();
}

在网络服务中:

@POST
@Consumes("multipart/mixed")
@Path("/upload")
public Response post(MultiPart multiPart) {

    BodyPartEntity bpe = (BodyPartEntity) multiPart.getBodyParts().get(0)
            .getEntity();

    boolean isProcessed = false;
    String message = null;
    try {
        InputStream source = bpe.getInputStream();
        BufferedImage bi = ImageIO.read(source);

        File file = new File("E:/Goodies/tmp" + "123.jpg");

        // storing the image to file system.
        if (file.isDirectory()) {
            ImageIO.write(bi, "jpg", file);
        } else {
            file.mkdirs();
            ImageIO.write(bi, "jpg", file);
        }
        isProcessed = true;
    } catch (Exception e) {
        message = e.getMessage();
    }

【讨论】:

    【解决方案4】:

    您需要检查的事项很少

    将 mimepull.jar 添加到您的库或使用 Maven

    `<dependency>
        <groupId>org.jvnet.mimepull</groupId>
        <artifactId>mimepull</artifactId>
        <version>1.9.5</version>
    </dependency>`
    

    如果您正在处理文件,请确保在标题处发送 content-length content-type accept-encoding

    【讨论】:

      【解决方案5】:

      我在web.xml 中添加了这个。问题解决了。

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

      【讨论】:

        【解决方案6】:

        这是我的解决方法:

                WebResource webResource =
                        jerseyClient.resource("www.api.com");
                WebResource.Builder requestBuilder = webResource.getRequestBuilder();
                requestBuilder.header("content-type", "application/json");
                ClientResponse response = requestBuilder
                        .post(ClientResponse.class, mObjectMapper.writeValueAsString(new RequestObject(longUrl)));
                String text = response.getEntity(String.class);
                ResponseObject outcome = mObjectMapper.readValue(text, ResponseObject.class);
        

        我使用 Jackson ObjectMapper 序列化请求负载,同样使用 ObjectMapper 将结果反序列化为 ResponseObject 实例。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-08-30
          • 1970-01-01
          • 2012-01-25
          • 2017-09-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多