users@jersey.java.net

Re: [Jersey] Jersey JAXB Inheritance

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Tue, 31 Mar 2009 09:19:41 +0200

On Mar 31, 2009, at 7:36 AM, Ido Ran wrote:

> Hi,
> I'm developing application and expose it to a client front-end using
> web application running in Jersey and using JAXB for serialization.
> I have several entities in my application, for example NetworkObject
> and Relation. NetworkObject has id and name and Relation has
> fromObject and toObject which, as you might guessed, point to
> reference of NetworkObject.
>
> I'm considering Relation to be sub-resource of NetworkObject.
> Since I want changes to single NetworkObject to be atomic I'm using
> a UnitOfWork approach as follows:
> I have base class UowCommand and derive from it several sub-classes
> like ChangeName, AddRelation, UpdateRelation, RemoveRelation. Each
> sub-class contain enough information to perform the action on the
> server side.
>
> The problem :)
>
> I don't know how to explain JAXB to de-serialize list of UowCommand
> which actually have sub-class instances in it.
>
> Meaning, it is very important to preserve the order in which the
> actions occur so I have a class which has list of UowCommand. On the
> client side I serialize the list and get something like this:
> <unitOfWork>
> <commands>
> <addRelation toObject="123" />
> <addRelation toObject="456" />
> <removeRelation toObject="789" />
> </commands>
> <unitOfWork>
>
> How should I annotate the JAXB classes on the server so I'll be able
> to de-serialize this kind of xml.


Have you got this to work with JAXB when serializing?

I would need to see the existing JAXB beans to help you better.

To de-serialize you need to set up the JAXB context correctly with
your classes as Jersey will not be able to determine the complete set
of JAXB objects since the unitOfWork bean is general and will not have
specific references to the command objects i presume. To do that you
need to implement a ContextResolver<JAXBContext>, for example:

   @Provider
   public final class JAXBContextResolver implements
ContextResolver<JAXBContext> {

       private final JAXBContext context;

       private final Set<Class> types;

       private final Class[] cTypes = { ... };

       public JAXBContextResolver() throws Exception {
           this.types = new HashSet(Arrays.asList(cTypes));
           this.context = JAXBContext.newInstance(cTypes);
       }

       public JAXBContext getContext(Class<?> objectType) {
           return (types.contains(objectType)) ? context : null;
       }
   }



> Another question: is it possible to do the same (sub-class) with
> JSON? Maybe with jettison notation?
>

JSON de/serialization is supported with JAXB beans.

See the JSON from JAXB sample:

   http://download.java.net/maven/2/com/sun/jersey/samples/json-from-jaxb/1.0.2/json-from-jaxb-1.0.2-project.zip


> The reason I'm straying from RESTful way, a little, is because my
> object graph (and their representation) can become very large. I
> think that sending whole resource representation for every tiny
> update might be overkill.

That design decision is independent of REST. You should expose what
you think is important information as resources, whether it be fine
grained or not. Sometimes a controller based-URI is appropriate for
update using POST, using say the "unit of work" you have defined that
declares changes.


> For example, if I only wish to change the name of an object I have
> to create full representation include all it relations.

Yes, correct, as per the semantics of PUT.

Paul.

> Also I need a way to change multiple properties (as the example
> above) and make sure it is atomic change.
>
> Thank you very much,
> Ido.
>