I meant to send this message yesterday evening but got distracted a bit ...

I think you're after a multipart-related content type (or some other multipart/*). At the moment CXF JAX-RS does not support a javax.activation.DataSource or
other Java Activation Framework types. JAX-RS spec requires that DataSource is 
supported out of the box - so CXF JAX-RS will do it
eventually - given that there's a fairly advanced support for it in the 
XmlBinding available already.

In meantime, a workaround is to write a custom message body reader which will 
use a JAF to convert an input stream into, say,
MultipartDataSource[1] and use a signature like this one :

@PUT
@Path("/new")
       public String testPut(MultipartDataSource dataSource) {
             Customer c = getCustomer(dataSource.getBodyPart(0));
             ZipInputStream is = getStream(dataSource.getBodyPart(1));
       }

This is a bit too low-level but it's doable.

Now, you can actually hide all this code in the MessageBodyReader, possibly 
relying on JAX-RS MessageBodyWorkers :

public class CustomerInfoReader implements MessageBodyReader<CustomerInfo> {
    @Context HttpHeaders headers;
    @Context MessageBodyWorkers workers;

     public boolean isReadable(...) {
          return "multipart/related".equals(headers.getMediaType().toString());
     }

     public CustomerInfo readFrom(..., InputStream is) {

          CustomerInfo customerInfo = new CustomerInfo();
          // use JAF to do it or look at the CXF source code, I don't remember 
the detail :-)
          MultipartDataSource source = getFrom(is);
          BodyPart part1 = source.getBodyPart(0);
          // use JAXB directly or rely on a provided JAXB reader :

          Customer c = workers.getMessageBodyReader(Customer.class,
                                                 
MediaType.valueOf(part1.getContentType()), new Annotation[]{}).readFrom(...,
part1.getInputStream());


          customerInfo.setCustomer(c);
          customerInfo.setCustomerAttachment(source.getBodyPart(1));
          return customerInfo;
     }


}

@PUT
@Path("/new")
public String testPut(CustomerInfo ci) {
}

Perhaps its the best option if you'd like to keep the low-level details out of 
the application code.

If you wanted to upload only a file then you'd have more simpler options, like using InputStream or Reader in the method signature for ex...

Cheers, Sergey

[1] http://java.sun.com/j2ee/1.4/docs/api/javax/mail/MultipartDataSource.html

----- Original Message ----- From: "deniak" <[EMAIL PROTECTED]>
To: <[email protected]>
Sent: Thursday, July 31, 2008 9:13 AM
Subject: Re: CXF and http body



Ok, but what can I do if I'd like to send the XML file (with RequestEntity)
and a zip file
include in the request??





Arul Dhesiaseelan wrote:

setRequestBody is deprecated in HttpClient 3.x. You should instead use
setRequestEntity(RequestEntity).

setRequestBody is removed in HttpClient 4.x.

AFAIK, Jersey (JAX-RS implementation from Sun) Client API does not
support this method.

-Arul

deniak wrote:
Hi all,

I'm just starting with web services and CXF and I'd like to know if it's
possible to deal with the request body with CXF.

I just created a client like that:

File customer = new File("pathToXMLFile");
File body = new File("AZipFile");
PutMethod put = new PutMethod("http://localhost:8080/test/new";);
put.addRequestHeader("Accept", "text/xml");
FileRequestEntity entity = new FileRequestEntity(customer, "text/xml;
charset=ISO-8859-1");
put.setRequestEntity(entity);
put.setRequestBody(body);
HttpClient httpclient = new HttpClient();
httpclient.executeMethod(put);


Here's my server:

@Path("test")
public class TestServlet {
        @PUT
@Path("/new")
        public String testPut(Customer customer) {
              .....
        }
}

----------------------------
IONA Technologies PLC (registered in Ireland)
Registered Number: 171387
Registered Address: The IONA Building, Shelbourne Road, Dublin 4, Ireland

Reply via email to