File uploads with CXF Multipart form posts

Now that the title of this post has scared off all non-technical readers of my blog (sorry Mom! :)) I wanted to come back to hopefully regular posting with a bang.

I’ve been working a side project that involves a REST web service. I needed to upload a file along with some identifying data and for the life of me I couldn’t figure it out. I could get files to upload with a PUT or send the data with a POST, but couldn’t do both in one call. I finally got it and I want to keep it here since finding full examples for CXF stuff isn’t easy.

First, here’s the interface for the method:


@POST
@Path(“/stuff”)
@Produces(“application/json”)
@Consumes(MediaType.MULTIPART_FORM_DATA)
public String doStuff(@Multipart(“id”)Integer id, @Multipart(“data”)String foo, @Multipart(“image”)byte[] image);


The @Consumes annotation with the @Multipart annotations on the parameters is the vital bit. These allows you to just grab the parameters in the implementation and not mess around with getting the Multipart Attachments and all that.


@Override
public String doStuff(Integer id, String foo, byte[] image) {
}


I’m sending the file with Android, using the HttpClient api.


HttpPost request = new HttpPost(url);

MultipartEntity mentity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
ByteArrayBody imgBody = new ByteArrayBody(imageBytes, “image/jpeg”, “image”);
mentity.addPart(“image”, imgBody);

//add headers
for(NameValuePair h : headers)
{
request.addHeader(h.getName(), h.getValue());
}

for(NameValuePair p : params) {
mentity.addPart(p.getName(), new StringBody(p.getValue(), “text/plain”, Charset.forName( “UTF-8” )));
}

request.setEntity(mentity);

executeRequest(request, url);


This is nice and simple, and it works fine for me. Hopefully this will be helpful to you too if you’re like me and Google this issue a hundred times. :)