8

I am using Jersey client to hit a PHP web service for image uploading functionality. I am getting the following exception:

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

This is the code I am using:

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

How can this exception be resolved?

Bogdan
  • 23,890
  • 3
  • 69
  • 61
aaaa
  • 487
  • 4
  • 13
  • 24
  • can you please share some more code...like how you create your form .In normal situations your code would work.. – mvlupan Mar 24 '13 at 07:04

6 Answers6

13

Register the MultiPartWriter provider when creating the Client:

ClientConfig cc = new DefaultClientConfig();
Client client;

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

If using Maven, these are the dependencies you need in your 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>
9

Jersey (server or client) has providers that support the conversion of a Java type to a stream and vice versa. Your code returns (or receives) a Java object and based on the type of the object and the content type you are using, Jersey looks for an appropriate provider to do the marshalling (or unmarshalling).

The providers implement the MessageBodyReader or MessageBodyWriter interfaces and for every Java type and content type combination your application uses you must have a provider that knows how to handle the combination.

The messages you are getting is telling you that Jersey can't find a provider that knows how to marshal a FormDataMultiPart object with a multipart/form-data mime type. You need to provide one, and if I'm not mistaken the default implementation is found in the jersey-multipart.jar and mimepull.jar files.

Bogdan
  • 23,890
  • 3
  • 69
  • 61
  • 2
    Make sure to use the version of `jersey-multipart` which corresponds to the version of `jersey-core`. – Aram Kocharyan Dec 12 '13 at 02:24
  • The key the versioning may lie in the /META-INF/jersey-module-version. Each jersey jar file has this file and I suspect they must all match up. Once I got all my jars to be of the same version. The mimepull.jar doesn't have this, but should match what is in the jersey-multipart.jar pom.xml dependency. – user2708344 May 17 '17 at 18:46
2

I faced the same issue. It got solved by changing maven dependency for jersey-multipart jar from 1.0.2 to 1.8 version (Used the same dependency in client side as well as provider side.

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

Here's the complete piece of code I'm using

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

and in the webservice:

@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();
    }
Kisanagaram
  • 289
  • 2
  • 10
2

there are few things you need to check

add mimepull.jar to your lib or with Maven

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

And if you are working with file, make sure you send at the header the content-length content-type accept-encoding

Ofir Attal
  • 1,136
  • 10
  • 10
0

I added this in web.xml. Problem solved.

<init-param>
   <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
   <param-value>true</param-value>
</init-param>
croxy
  • 4,082
  • 9
  • 28
  • 46
Anil
  • 34
  • 3
0

Here's my work around:

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

I have used Jackson ObjectMapper to serialize the request payload and likewise deserialized the outcome into a ResponseObject instance using ObjectMapper.

Himadri Pant
  • 2,171
  • 21
  • 22