users@jersey.java.net

Re: [Jersey] using jaxb to stream a large data set

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Tue, 09 Feb 2010 18:59:41 +0100

On Feb 9, 2010, at 6:54 PM, Felipe Gaścho wrote:

> can you use Stax? http://jcp.org/en/jsr/detail?id=173
>

Yes, but you still need to marshall out the JAXB stuff unless you want
to write a lot of low-level StAX code.

The Jersey writing of collections does not bother using StAX and
instead writes fragments directly to the output stream:

     public final void writeTo(
             Object t,
             Class<?> type,
             Type genericType,
             Annotation annotations[],
             MediaType mediaType,
             MultivaluedMap<String, Object> httpHeaders,
             OutputStream entityStream) throws IOException {
         try {
             final Collection c = (type.isArray())
                     ? Arrays.asList((Object[])t)
                     : (Collection)t;
             final Class elementType = (type.isArray())
                     ? type.getComponentType()
                     : getElementClass(type, genericType);
             final Charset charset = getCharset(mediaType);
             final String charsetName = charset.name();

             final Marshaller m = getMarshaller(elementType, mediaType);
             m.setProperty(Marshaller.JAXB_FRAGMENT, true);
             if (c != UTF8)
                 m.setProperty(Marshaller.JAXB_ENCODING, charsetName);
             writeList(elementType, c, mediaType, charset, m,
entityStream);
         } catch (JAXBException ex) {
             throw new WebApplicationException(ex, 500);
         }
     }

     public final void writeList(Class<?> elementType, Collection<?> t,
             MediaType mediaType, Charset c,
             Marshaller m, OutputStream entityStream)
             throws JAXBException, IOException {
         final String rootElement = getRootElementName(elementType);
         final String cName = c.name();

         entityStream.write(
                 String.format("<?xml version=\"1.0\" encoding=\"%s\"
standalone=\"yes\"?>", cName).getBytes(cName));
         entityStream.write(String.format("<%s>",
rootElement).getBytes(cName));

         for (Object o : t)
             m.marshal(o, entityStream);

         entityStream.write(String.format("</%s>",
rootElement).getBytes(cName));
     }

Paul.


> On Tue, Feb 9, 2010 at 6:52 PM, Paul Sandoz <Paul.Sandoz_at_sun.com>
> wrote:
>>
>> On Feb 9, 2010, at 6:44 PM, Moiz Dohadwala wrote:
>>
>>> Paul,
>>>
>>> Thanks. I was leading that way myself. My concern regarding using
>>> jaxb
>>> fragments for streaming was the ability to marshal to json
>>> seamlessly. I
>>> guess I will find out.
>>>
>>
>> You should be able to do that if you return a collection with a lazy
>> iterator implementation.
>>
>> The StreamingOutput can work for XML or JSON but you need to do
>> that work
>> using JSONJAXBContext when JSON is used. Or say using Jackson
>> instead.
>>
>> Paul.
>>
>>> -Moiz
>>>
>>> -----Original Message-----
>>> From: Paul.Sandoz_at_Sun.COM [mailto:Paul.Sandoz_at_Sun.COM]
>>> Sent: Tuesday, February 09, 2010 9:06 AM
>>> To: users_at_jersey.dev.java.net
>>> Subject: Re: [Jersey] using jaxb to stream a large data set
>>>
>>>
>>> On Feb 9, 2010, at 1:15 AM, Moiz Dohadwala wrote:
>>>
>>>> Hello,
>>>>
>>>> We am currently using jersey to build a set of reports. The reports
>>>> on the UI are paginated, since the data set can potentially be very
>>>> large. However, we need to provide a download option to allow the
>>>> user to download the entire set. Currently we have been using jaxb
>>>> to provide support for xml as well as json. What options to we have
>>>> to support streaming streaming using jaxb in jersey?
>>>>
>>>
>>> JAXB is not a streaming-based API so i guess any approach would be
>>> to
>>> utilize "fragments" of JAXB.
>>>
>>> The only current support for fragments of JAXB is returning a
>>> List<T>
>>> or Collection<T> (and it would be really easy to extend to support
>>> Iterator<T>).
>>>
>>> You could implement a Collection that supports a lazy iterator.
>>>
>>> Alternatively you could implement the JAXB fragment marshaling
>>> yourself using StreamingOutput [1].
>>>
>>> Paul.
>>>
>>> [1]
>>> https://jsr311.dev.java.net/nonav/javadoc/javax/ws/rs/core/StreamingOutput.html
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>
>>
>
>
>
> --
> ------------------------------------------
> Felipe Gaścho
> 10+ Java Programmer
> CEJUG Senior Advisor
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>