Yes, basically I followed the restful_dispatch sample, but built over it 
somewhat complex.
I try to show an example:

@XmlRootElement(name="customer")
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
                
        @XMLElement
        private String id;
        
        // other fields
        ...
        ...     
        
        // say email attachment
        @XmlAttachmentRef
        private DataHandler email;
        ...
}

I generate schema from this and that becomes basis for a request/response below.
To simplify let's say the service accepts customer and returns customer.

// Use dispatch provider that accepts/returns application/xml. As far as I 
understand here, I cannot use the high-level
// JAXB utilities that CXF provides.
// Here's what I've got without the email attachment. with just xml body.

public class CustomerServiceProvider implements Provider<DataSource> {
        
        
        public DataSource invoke(DataSource ds) {
                ...// do all required validation
                
                // Create Customer object from request
                JAXBContext jaxbCtx = JAXBContext.newInstance(< Customer and 
other classes>);
                Unmarshaller unmarshaller = jaxbCtx.createUnmarshaller();
                unmarshaller.setSchema(<generated schema>);
                JAXBElement<?> jaxbElem = unmarshaller.unmarshal(...);
                Object obj = jaxbElem.getValue();
                // obj is now Customer
                
                // do biz logic here
                
                // Now write back a new Customer object.                        
                
                Marshaller marshaller = jaxbCtx.createMarshaller();     
                marshaller.setSchema(schema);
                StringWriter sw = new StringWriter();
                marshaller.marshal(< JAXBElement for Customer >,sw);
                
                return <DataSource from sw>
        }
}

Now, to add the email attachment, I need to support multipart/related or 
multipart/mixed. I guess if client sends such a request, CXF provides all the 
necessary attachments in the ds.
My problem is how I could return a DataSource containing the customer as root 
and the e-mail as related/mixed type attachment.
Should I create something similar to 
MessageModeInInterceptor$MultiPartDataSource and convert to byte source myself 
or does CXF have something to make it easier?


-Vinay



-----Original Message-----
From: Sergey Beryozkin [mailto:sberyoz...@gmail.com] 
Sent: Tuesday, May 21, 2013 4:56 AM
To: users@cxf.apache.org
Subject: Re: REST with JAX-WS Provider: attachment support

Hi
On 21/05/13 00:10, Penmatsa, Vinay wrote:
> Hi Sergey,
> Do these annotations apply to Provider based REST services? I have used these 
> in JAX-RS services, but not for JAX-WS provider based stuff.
> What I've done with XML payloads (payload mode) is
> 1. take the request xml, manually unmarshal using JAXB
> 2. process
> 3. create and return marshaled string as DataSource.
>
> With attachments (I guess message mode), in your example, if I have a result 
> in the form of JAXB root model object, how would I return a DataSource so 
> that CXF can process the response into Multipart? I was thinking I have to 
> build something like MultiPartDataSource manually.
>

Hmm... May be I've misunderstood your question.
I'm presuming you have the same interface exposed as JAX-WS and JAX-RS 
endpoints ? Can you type some code and show what exactly do you have in 
mind ?

Thanks, Sergey

> -Vinay
>
>
>
> -----Original Message-----
> From: Sergey Beryozkin [mailto:sberyoz...@gmail.com]
> Sent: Monday, May 20, 2013 4:59 PM
> To: users@cxf.apache.org
> Subject: Re: REST with JAX-WS Provider: attachment support
>
> Hi
> On 20/05/13 21:28, Penmatsa, Vinay wrote:
>> Hi,
>> I have a REST service based on JAX-WS Provider and Dispatch (implementing 
>> Provider<DataSource>). Until now, I accept/produce only XML. Now, I have to 
>> support attachments.
>> Now, it seems like request should be "multipart/related" as only 
>> AttachmentInInterceptor is part of the chain by default. I could probably 
>> change that to use AttachmentInputInterceptor instead. The question is how 
>> can I can I return MultipartBody? Is there in-built support for that or 
>> should I create my own DataSource and handle with an custom out interceptor?
>
> Adding @Consumes("multipart/related") should be enough to get DataSource
> representing the root attachment, and similarly adding
>
> @Produces("multipart/related") is nearly enough to get out DataSource
> converted to the multipart payload, except that you also need to specify
> the content type of this root type, so it can look like this:
>
> @Produces("multipart/related;type=application/xml")
> @Consumes("multipart/related")
> public DataSource a(DataSource ds) {
>       return ds;
> }
>
> My understanding you'd like to have a 100% portable code, right ?
>
> Note that up to CXF 3.0-SNAPSHOT, the input 'ds' parameter will
> represent the root part of the incoming payload. The response DataSource
> also represents the root part of the outgoing attachment.
> I think it is rarely that someone will want to have 'ds' (in this case)
> representing the actual non-parsed multipart payload or manually build
> the actual multipart body, so originally I went that path.
>
> In CXF 3.0, due to JAX-RS 2.0 TCK 'insistence' on the types like
> DataSource, InputStream, byte[] be supported by basic pre-packaged
> providers, the above will slightly change to:
>
> @Produces("multipart/related;type=application/xml")
> @Consumes("multipart/related")
> @Multipart
> public DataSource a(@Multipart DataSource ds) {
>       return ds;
> }
>
> Where CXF @Multipart annotation marks in and out parameters as multipart
> bodies. Without @Multipart the 1st example above will produce a portable
> but more complex code (meaning DataSource will have to be manually
> parsed or used to create the out payload manually)
>
> Sergey
>
>
>>
>>
>> Thanks,
>> Vinay
>>
>>
>
>

Reply via email to