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