Sergey recently implemented multipart support for CXF JAXRS implementation which is available in 2.2-SNAPSHOT. He talks more about the feature in his blog here. It certainly provides a simpler programming model like any other CXF frontends, which I always liked with the CXF project and prime reason for its growing popularity among developers. It supports multipart/related, multipart/alternative, multipart/mixed and multipart/form-data out-of-the-box. I gave it a spin and programming multiparts in CXF was like a piece of cake and you would know why by looking at the code shortly. The ability to reuse your code across SOAP and REST is the key differentiator for CXF when compared to Jersey and RESTEasy. I will leave this discussion for another blog post.

I will be reusing the same example which I used in my earlier blog entry for describing Jersey multiparts.

In this sample, I used the brand new HttpClient 4.0 API as the REST client for invoking restful services, as CXF does not ship one yet. HttpClient 4.0 API is completely redesigned and addresses most of the architectural shortcomings from its previous releases, and this version is not backwards compatible.

Here is my maven dependencies:





Here is the Multipart resource, which processes two body parts and returns the entity with the rank set on the Project bean.

import org.apache.cxf.helpers.IOUtils;
import org.apache.cxf.jaxrs.ext.multipart.Attachment;
import org.apache.cxf.jaxrs.ext.multipart.MultipartBody;

import javax.activation.DataHandler;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import java.util.List;

public class MultipartResource {
    public Response processMultiparts(MultipartBody multipartBody) {
        List<Attachment> attachments = multipartBody.getAllAttachments();
        DataHandler dataHandler1 = attachments.get(0).getDataHandler();
        DataHandler dataHandler2 = attachments.get(1).getDataHandler();
        Project project = null;
        try {
            project = getProjectFromInputStream(dataHandler1.getInputStream());
            System.out.println("Processing Attachment 1 ...");
            System.out.println("name : " + project.getName());
            System.out.println("description : " + project.getDescription());
            System.out.println("license : " + project.getLicense());
            System.out.println("SVN URL : " + project.getSvnURL());
            System.out.println("homepage : " + project.getHomepage());

            System.out.println("Processing Attachment 2 ...");
            String comment = getStringFromInputStream(dataHandler2.getInputStream());
            System.out.println("Comment : " + comment);

        } catch (Exception e) {
            throw new WebApplicationException(500);
        return Response.ok(project).build();

    public static Project getProjectFromInputStream(InputStream is) throws Exception {
        JAXBContext c = JAXBContext.newInstance(new Class[]{Project.class});
        Unmarshaller u = c.createUnmarshaller();
        Project project = (Project) u.unmarshal(is);
        return project;

    public static String getStringFromInputStream(InputStream in) throws Exception {
        CachedOutputStream bos = new CachedOutputStream();
        IOUtils.copy(in, bos);
        return bos.getOut().toString();


Start the Jetty based CXF JAXRS server which deploys the multipart resource as a singleton.

public class CXFRestServer {
    public static void main(String[] args) {
        JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean();
                new SingletonResourceProvider(new MultipartResource()));
        System.out.println("Server started.");

HttpClient APIs are used to POST the multipart entites to the CXF multipart resource. The first part is a XML File and the second part is a String content. Finally, it processes the response received from the resource.

public class TestClient {

    public static void main(String[] args) throws Exception {
        HttpClient httpclient = new DefaultHttpClient();
        HttpPost httppost = new HttpPost("http://localhost:8081/multipart");
        FileBody bin = new FileBody(new File(TestClient.class.getResource("/project_summary.xml").getFile()));
        StringBody comment = new StringBody("Project summary.");

        MultipartEntity reqEntity = new MultipartEntity();
        reqEntity.addPart("project", bin);
        reqEntity.addPart("comment", comment);


        System.out.println("executing request " + httppost.getRequestLine());
        HttpResponse response = httpclient.execute(httppost);
        HttpEntity resEntity = response.getEntity();

        if (resEntity != null) {
            System.out.println("Response content length: " + resEntity.getContentLength());
            System.out.println("Response content type: " + resEntity.getContentType().getValue());
            System.out.println("Project Rank : " + MultipartResource.getProjectFromInputStream(resEntity.getContent()).getRank());
        if (resEntity != null) {            

Place project_summary.xml in your root classpath.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <description>Apache CXF is an open source services framework.</description>
    <license>ASL 2.0</license>

This is just one approach of doing multiparts with CXF JAXRS implementation. You can dig into the unit tests to see all possible approaches to handle multiparts with in restful resources. HttpClient 4.0 API is cleaner and flexible and could potentially become a standard API for accessing RESTful web services in Java.

Update (4/11): The sample is updated to use the 2.2 release. The sources can be downloaded from here.

Possibly Related Posts:


I am currently employed with Flux Corporation, Houston. This blog does not reflect the position or opinion of my employer. I'll blog my experience with things I'm fascinated with software and programming.


Nickaj · March 30, 2009 at 5:29 am

good blog post ! Arul , it is very useful if you can upload complete source codes for this somewhere..?

Arul · April 11, 2009 at 5:38 pm

Hi Nickaj,


The sources are now attached to the blog entry.


Tom · June 8, 2009 at 3:39 pm

Hello Arul,

If I use curl to upload an image to cxf, the image size keep growing. Looks like it enter an infinite loop.

Any suggestions would be much appreciated.

DataHandler dataHandler1 = attachments.get(0).getDataHandler();

try {
//File outFl = new File(“c:\\tmp\\” + imgName);
File tmpFl = new File(“/image/” + image.getF1Username());
if (!tmpFl.exists()) {
File outFl = new File(“/image/” + image.getF1Username()+ “/” + image.getImageName());

FileOutputStream flOut = new FileOutputStream(outFl);
int anInt;
while ((anInt = dataHandler1.getInputStream().read()) != -1) {


} catch (IOException ex) {
DigLockLogger.record(Level.SEVERE, ImageServicesResource.class.getName() + “.postImage “,

cir.setStatusMessage(“Failed to persist the contact image: ”
+ ex.getMessage());

Arul · June 14, 2009 at 10:52 pm

Hi Tom,

I believe you got a bug in your code. Change your code as shown below, and it should work:

InputStream in = dataHandler1.getInputStream();
while ((anInt = != -1) {


Shivakumar · December 13, 2009 at 11:55 pm

Please could add a example code for Multipart data as a Response .

Arul · December 15, 2009 at 10:04 pm

Hi Shivakumar,

Here is an example from CXF system tests:

public MultipartBody addBookFormImage(MultipartBody image) throws Exception {
return image;

Is this something you were looking for?


Saravanan Ramamoorthy · May 19, 2010 at 11:37 pm

Hi Arul,

I tried to send attachments from Jax-Rs.
I need all content – headers so I have used the Attachment class and passing DataHandler and MultiValuedMap parameters.
I set all the content headers in the MultiValuedMap.

I am able to get all content headers exception Content-Location.
The first attachment’s Content-Location retrieves correctly but the subsequent Content-Location ‘s are changed to lower case(content-location) and the values are set to null.

Please suggest me.

Saravanan R

brian · July 14, 2010 at 11:37 am

Thx! Not much documentation on multipart handling with REST clients in the books.

oceanz · October 5, 2010 at 12:50 pm


Whenever I try to get a input as mulitpart, I always get the exception:
Caused by:
at org.apache.cxf.jaxrs.client.AbstractClient.reportNoMessageHandler(
at org.apache.cxf.jaxrs.client.AbstractClient.writeBody(
at org.apache.cxf.jaxrs.client.ClientProxyImpl$BodyWriter.handleMessage(

My request method is :
Device addDevice3(Panel p)

Can you please help on this

Comments are closed.