users@jersey.java.net

[Jersey] Re: Pluggable StAX message body writers as streaming alternative to JAXB POJO's?

From: Tatu Saloranta <tsaloranta_at_gmail.com>
Date: Fri, 25 Mar 2011 10:10:25 -0700

On Thu, Mar 24, 2011 at 11:00 PM, Casper Bang <casper.bang_at_gmail.com> wrote:
>> Stax API is for XML; although some libraries like Jettison (ab)use it
>> to produce kind of JSON.
>> But it is not a general way to produce formats other than XML; I can't
>> think of a Java API that does this.
>
> I am not sure I see a great difference between (ab)using JAXB annotations to
> generate JSON vs. doing it based on StAX events - both  caters to a concrete
> format of XML and can be seen as a superset to JSON (which has no
> namespaces, no atributtes, no collection wrappers etc.).

While I agree in that using JAXB annotations is not ideal (and I
sometimes with I never added support in Jackson.... when new edge
cases are found), I disagree in that these would be similar levels of
disgressions. :)
But this is probably more of a sidetrack so I'll leave out discussion
on impedance mismatch between XML vs JSON, as compared to impedance at
annotation level.
I just think latter is quite a bit lower: I think use of JAXB
annotations for producing/consuming JSON works much better than using
Stax interface to handle things (as per Jettison). Neither is perfect,
but other has more fundamental issues (single-element array or
element? no one knows!)

>> So in that sense, ability to use streaming is currently a data-format
>> specific thing.
>
> JAXB is obviously a handy way to assign mapping meta-data to POJO's, OTOH
> you effectually pollute your model and makes it impossible to use the same
> POJO to emit different projections (i.e. limit depth, elements

Right -- ideally I would like to see more generic property definitions
("bean overrides").
There are many common things that could be standardized, for naming;
and using some sort of extension mechanism
(for XML you need namespaces, attribute vs element). In a way, it
could be Bean 2.0 specification.

> or attributes depending on resource context). Both seems related to
> the data-format (or rather, data-representation).

Yes, there are things that go above and beyond common subset; mostly
(or almost completely) these are for XML.
But I could see the need for other formats, when extending beyond just
XML and JSON (I have tackled BSON, will try CSV in future, as an
example).

>> I am not sure JAX-RS or Jersey should try to standardize on this,
>> given that there is no way to make it really generic.
>
> Again, not sure I see a great difference between returning a full POJO tree
> with meta-data vs. lazily streaming akin to individual JAXB nodes. The main
>  difference just seems to be *when* the message body writers starts to get
> something to work with and starts sending a response back to the client. But
> perhaps there's something I am missing.

I do not disagree with that. All I am saying is that this should not
be represented in terms of Stax abstractions (XMLStreamWriter,
XMLStreamReader), since this is not adequate for purposes of JSON.

I may have read too much into your statement there; if you did not
imply that API would use Stax abstractions, then we might not be in
disagreement.

>> For output it is actually easy to do streaming output, by using
>> StreamingOutput wrapper, which gets invoked by Jersey, with
>> OutputStream to send output to.
>
> Yes it's fairly easy, but to obtain any kind of reuse between multiple
> representations (i.e. XML and JSON), one has to invent a custom callback
> layer between getting the context to build a response (i.e. iterating over a
> resultset) and actually constructing the result (writing nodes via StAX,
> XStream, Jettison etc.). It's this step I am seeking to generalize in light
> of OData (and other) query language and dynamic results on top of Jersey.

I can understand wish to do so, but I don't see suitable components available.

But just to be clear: can you explain a specific use case? I can think
of many (like reading DB query results, writing out without
intermediate POJOs), but I don't want to assume they are ones you are
thinking of. I could also see the case of incremental output, for
sequence of objects, but being written earlier before getting all the
results.

In that case, one could handle this without low-level interfaces by
exposing accessors for Iterable<T>. This would need work with backend
objects, so backends would be separate, but this would be mostly
internal detail for Jersey/JAX-RS developers.

>> For input side there isn't equivalent abstraction (due to mapping
>> needs), so MessageBodyReader impl is needed.
>
> Right, one must assume that a matched resource and headers/parameters passed
> to it, is enough context to work with. Such message body readers would
> almost by definition need to be event based or could not possibly map to
> type-safe Java structures.
> Anyway, just throwing some ideas around. Thanks for participating. :)

Yeah no, new ideas are good, discussions help smooth out kinks.
The main reason I am bit sensitive to ideas of Stax-with-JSON are
really due to boatloads of issues that Badgerfish and Jettison caused;
kind of once bitten twice shy.
And since I have implemented JSON-and-XML backends: Jackson has a
module to also do XML. So I am familiar with specific issues and would
want to avoid some of the ones I have had to work with from being
repeated, if possible.

-+ Tatu +-