users@jersey.java.net

Re: [Jersey] Jersey JAXB Inheritance

From: Jakub Podlesak <Jakub.Podlesak_at_Sun.COM>
Date: Mon, 11 May 2009 14:37:14 +0200

Hi Janne,

On Mon, May 11, 2009 at 08:32:35AM +0200, Kytömäki, Janne wrote:
> Hi,
>
> An old thread, but I finally found some time to test inheritance with Badgerfish notation. The case I described seems to work with it, as you suggested.
>

Great. But as you write, i understand BadgerFish is a notation, which is not 100 % satisfactory
for certain cases (human/JavaScript readability)

> As it would be much work to port our application from mapped to Badgerfish notation, I was delighted to see from the SVN logs that you've started working on bringing namespace support to the natural JSON notation. If this will also make the mentioned inheritance problem go away, this is great news.

For ceratin cases in the inheritance area, i additionaly need to fix layering
of JSON/STaX in the message body workers to get it work properly.
I used to push this out, mainly for other higher priority tasks, but now
i want to spend some time on it and get it fixed finally.
I want the fix to come to the release, which is plan right before J1 (by eof May).

>
> About natural notation: are there any plans to add any more configurability to it? I haven't much tested it, but AFAIK for instance it doesn't currently support disabling the root unwrapping, which we are using with the mapped notation. If we switch to natural notation, should we get rid of depending on the root element, or might this option be added in the near future?

Root unwrapping is enabled by default for natural notation, and in fact
this breaks things to work properly in certain cases when inheriting beans.
I plan to introduce an option to keep the root element in, even for the natural
notation, which should help fix the inheritance issue.

>
> By the way, testing out Jersey 1.1.0ea, I came across a JSON deserialization problem using mapped notation. I have an object, that has a subobject property, like this: "{ a: { b: { c: 1} } }". Posting the object like this to Jersey works fine, but if the said subproperty is empty, our application posts it as "{a: { b: {} } }". This caused Jersey to throw:
>
> java.lang.IllegalArgumentException: local part cannot be "null" when creating a QName
> at javax.xml.namespace.QName.<init>(QName.java:246)
> at javax.xml.namespace.QName.<init>(QName.java:299)
> at com.sun.jersey.json.impl.reader.JsonXmlStreamReader.generateEEEvent(JsonXmlStreamReader.java:694)
>
> Is "{a: { b: {} } }" illegal syntax? In any case, the same used to work before. By changing JsonXmlStreamReader's rows 685 and 693 from
>
> if (!"$".equals(name)) {
>
> to
>
> if (!"$".equals(name) && name != null) {
>
> seemed to fix the problem.

Thanks for the tip. Will add a test case and check the fix in.

Jakub

>
> Regards,
> Janne
>
> Jakub wrote:
> >Hi,
> >
> >please look at the very end...
> >
> >On Wed, Apr 01, 2009 at 11:51:56AM +0200, Paul Sandoz wrote:
> >>
> >> On Mar 31, 2009, at 3:47 PM, Kytömäki, Janne wrote:
> >>
> >>> Hi,
> >>>
> >>>>> Another question: is it possible to do the same (sub-class) with
> >>>>> JSON? Maybe with jettison notation?
> >>>
> >>> I'd also like to get de-serialization of JSON objects
> >>> with inheritance working, but haven't figured out how to do it yet,
> >>> at least with the default JSON notation. For example:
> >>>
> >>> @GET
> >>> @Path("/animals/")
> >>> public AnimalList getAnimals(){
> >>> AnimalList al = new AnimalList();
> >>> al.addAnimal(new Dog("Fifi"));
> >>> al.addAnimal(new Cat("Daisy"));
> >>> return al;
> >>> }
> >>>
> >>> @PUT
> >>> @Path("/animals/")
> >>> public Animal addAnimal(Animal a){
> >>> return a;
> >>> }
> >>>
> >>> .. where:
> >>>
> >>> @XmlRootElement(name="animalList")
> >>> public class AnimalList{
> >>> private List<Animal> animals = new ArrayList<Animal>();
> >>> ..
> >>> }
> >>>
> >>> @XmlRootElement(name="animal")
> >>> public class Animal {
> >>> private String name;
> >>> ..
> >>> }
> >>>
> >>> @XmlRootElement(name="cat")
> >>> public class Cat extends Animal {
> >>> ..
> >>> }
> >>>
> >>> @XmlRootElement(name="dog")
> >>> public class Dog extends Animal {
> >>> ..
> >>> }
> >>>
> >>> Cat and Dog classes need to be set up in the JAXB context, like
> >>> Paul wrote.
> >>
> >> Thanks, hopefully that example will help Ido.
> >>
> >> <snip>
> >>> Default JSON notation doesn't support property namespaces, so the
> >>> "xsi:type" property isn't passed to JAXB and the object
> >>> is deserialized as an instance of the superclass. Not sure
> >>> why the root element doesn't translate to the correct subclass
> >>> in this example, but even if it did, it wouldn't help in the
> >>> cases, where the subclass is not the root element but a
> >>> subproperty.
> >>>
> >>> Another example can be found in jersey issue 113:
> >>> https://jersey.dev.java.net/issues/show_bug.cgi?id=113
> >>>
> >>> Could passing the xsi:type from JSON to JAXB in de-serialization
> >>> be possible with the other JSON notations?
> >>>
> >>
> >> Jakub, what do you think?
> >
> >I would bet badgerfish would work as this notation keeps
> >all of the XML info in JSON.
> >Can you try with JSONConfiguration.badgerFish().build() JSON config?
> >
> >~Jakub
>