Hi

The initial support for reading/writing collections is on the trunk now.
Writing/reading collections/arrays is supported for plain JAXB, only writing
is currently supported for JSON.
I'll be looking at fixing a JSON reading issue and optimizing it all.

By default, pluralized XMLRootElement name attribute will be used as a
wrapper, namespace-prefixed if needed, if no name attribute is there then a
lower-case pluralized class name will be used. This can be customized by
using setCollectionWrapperName on JAXB/JSON providers

thanks, Sergey
 

Sergey Beryozkin-2 wrote:
> 
> Hi Dan,
> 
> I'm doing 2) now, though it does now work quite well for JSON, but it's
> a good start. Will definitely look into using ASM as well...
> 
> Cheers, Sergey
> 
> -----Original Message-----
> From: Daniel Kulp [mailto:[email protected]] 
> Sent: 15 July 2009 19:23
> To: [email protected]
> Cc: Sergey Beryozkin
> Subject: Re: Handling Collection<JAXBElement> returns via JAX-RS
> 
> 
> Well, on the JAX-WS side of things, if a method returns something like 
> List<Foo> getFoos(), one of two things happens depending on if ASM is
> found on 
> the classpath:
> 
> If ASM is found:
> At startup time, we use ASM to generate a wrapper bean in memory that
> would 
> basically be:
> @XmlRootElement(....)
> @XmlType(....)
> public class  GetFoos {
>    @XmlElement(...)
>     List<Foo> foo;
>    ...
> }
> that is then put into the JAXBContext along with Foo.   Since this can
> be 
> determined up front that we need to do it, that works fine.
> 
> 
> 2) If ASM is NOT found, we cannot do that above.   Thus, it becomes a
> runtime 
> thing.   In THAT case, we manually write a wrapper element out to the 
> XMLStreamWriter and then literally do the equiv of:
> 
> for(Foo f : foos) {
>    marshaller.marshal(f, writer);
> }
> 
> and then close off the wrapper element.    I think you should be able to
> do 
> something similar to the latter within the JAXB provider.
> 
> 
> Dan
> 
> 
> 
> 
> On Tue July 14 2009 8:18:14 am Sergey Beryozkin wrote:
>> Hi Dan
>>
>> I've started doing some work in this area and at the moment some
> manual 
>> top-level element start/end serialization is being done. I'd like to
>> experiment a bit with using a generated Collection wrapper, for the
>> deserailzation to work too, but I'm kind of stuck a bit as JAXB
> complains,
>> while serializing this generated Collection instance that no context
> is
>> available for say Foo.class, for ex :
>>
>> List foos = new ArrayList();
>> foos.add(new Foo());
>> Collection c = new Collection();
>> c.getAny().addAll(foos);
>> // marshal this collection instance
>>
>> perhaps the solution is to create a shared JAXBContext for both Foo &
>> Collection, but is it the right approach ? My concern is that given
> that in
>> JAX-RS we don't know in advance all the types we may have to deal with
> due
>> to the dynamic subresource resolution, we may end up with contexts for
> Foo
>> & Collection, Bar & Collection, etc - though may be it's unlikely to
> happen
>> in practice... Dan K, Benson - is there any trick I may need to be
> aware to
>> make it work in the most efficient way ? thanks, Sergey
>>
>> > Hi,
>> >
>> > I'm writing a JAX-RS app and using CXF as the implementation.  I was
>> > having trouble wiring up some of my methods -- specifically, one
> that was
>> > to return a list of people:
>> >
>> > @GET
>> > @Path("/list")
>> > List<Person> getPersons();
>> >
>> > Trying to run that, I got NPEs, as List can't be written out as a
> root
>> > element by default.
>> >
>> > A lot of the advice that I saw involved adding extra collections,
> and
>> > changing the method signature to return the JAXBtized collection
> wrapper.
>> > Since this isn't strictly a REST call, this either means that
> everybody
>> > using the service call will have to unwrap the collection, or that I
> will
>> > have to code two methods every time I want to return a collection.
>> >
>> > Instead, I'd like to actually fix this in the providers at the core
> of
>> > CXF. I created a collection object of my own:
>> >
>> >    <complexType name="Collection">
>> >        <sequence>
>> >            <any minOccurs="0" maxOccurs="unbounded"></any>
>> >        </sequence>
>> >    </complexType>
>> >
>> > ... And then overrode the JAXBElementProvider.writeTo method:
>> >
>> > package us.XXXXXXXXX.iotool.jaxrs;
>> >
>> > import java.io.IOException;
>> > import java.io.OutputStream;
>> > import java.lang.annotation.Annotation;
>> > import java.lang.reflect.Type;
>> >
>> > import javax.ws.rs.WebApplicationException;
>> > import javax.ws.rs.core.MediaType;
>> > import javax.ws.rs.core.MultivaluedMap;
>> >
>> > import org.apache.cxf.jaxrs.provider.JAXBElementProvider;
>> >
>> > import us.XXXXXXXXX.iotool.model.Collection;
>> >
>> > public class CollectionJAXBElementProvider extends
> JAXBElementProvider {
>> >
>> > @Override
>> > public void writeTo(Object obj, Class<?> cls, Type genericType,
>> >     Annotation[] anns, MediaType m,
>> >      MultivaluedMap<String, Object> headers, OutputStream os)
>> >        throws IOException {
>> > try {
>> >  Object actualObject = checkAdapter(obj, anns, true);
>> >  // if it's a java.util.Collection, wrap it in our collection object
>> >  if (actualObject instanceof java.util.Collection) {
>> >    us.XXXXXXXXX.iotool.model.Collection collection = new
> Collection();
>> >    java.util.List list  =
>> >      new
> java.util.ArrayList((java.util.Collection)actualObject);
>> >    collection.setAnies(list);
>> >    actualObject = collection;
>> >  }
>> >
>> >  // now pass to the superclass
>> >  super.writeTo(actualObject, cls, genericType, anns, m, headers,
> os);
>> >  }  catch (WebApplicationException e) {
>> >   throw e;
>> >  } catch (Exception e) {
>> >   throw new WebApplicationException(e);
>> >  }
>> > }
>> >
>> > }
>> >
>> >
>> > This works fine -- any java.util.Collection will get wrapped in a
>> > <Collection> tag.
>> >
>> > There are a couple of downsides here:
>> >
>> > (1) Doing it in this provider means that it doesn't apply to my JSON
>> > provider.
>> > (2) I don't think that I have a great way to consume this on the
> client
>> > side as anything other than a wrapped collection (if that even
> works).
>> >
>> > Two sets of questions:
>> > (1) Can I get to my desired end -- transparently handling
>> > java.util.Collection objects -- without all this mucking about?  Can
> I do
>> > this with a XmlJavaTypeAdapter?
>> >
>> > (2) Is there a different spot in the chain where I can put this that
>> > would change the objects prior to their being consumed by any
> providers? 
>> > The documentation on the JAX-RS filters wasn't totally clear to me
> on
>> > this point.
>> >
>> > Thanks in advance,
>> > Dan
>> >
>> >
>> > -----
>> > CONFIDENTIALITY NOTICE: The information contained in this message
>> > may be privileged and confidential and protected from disclosure.
>> > If the reader of this message is not the intended recipient, or
>> > responsible for delivering it to the intended recipient, please
>> > be advised that any distribution, dissemination, copying or other
>> > transmission or use of the information contained in this message
>> > or its enclosed attachments is strictly prohibited.  Please
>> > notify us immediately if you have received this message in error
>> > by replying to the sender of the message and deleting it from
>> > your computer.  Thank you.
> 
> -- 
> Daniel Kulp
> [email protected]
> http://www.dankulp.com/blog
> 
> 

-- 
View this message in context: 
http://www.nabble.com/Handling-Collection%3CJAXBElement%3E-returns-via-JAX-RS-tp24262522p24517386.html
Sent from the cxf-user mailing list archive at Nabble.com.

Reply via email to