users@jaxb.java.net

Re: Using JAXB with generics

From: Wolfgang Laun <wolfgang.laun_at_gmail.com>
Date: Mon, 26 Oct 2009 11:05:27 +0100

You want to create XML for <countedCollection> according to the generic
class CountedCollection, with an arbitrary class being used for the elements
of the contained Vector record. The problem is that JAXB has to be made
aware of all the classes potentially occurring as Vector elements.

One way to get what you want might be to use a common superclass
AbstractRecord of all the classes in com.donotuse.jpa.* that might appear as
record instances instead of the generic parameter for Vector. Or, if there
is no gain in having this base class, simply use Object.

JAXB will marshal any type, as long as the class is entered into the
JAXBContext; so you might have to create this with
JAXBContext.newInstance( "com.donotuse.facade:com.donotuse.jpa" );

-W


On Mon, Oct 26, 2009 at 6:30 AM, Pratap Singh <p.singh11972_at_gmail.com>wrote:

>
> Hello helpful Internet citizens
>
> I'm getting to know the internals of Jersey and JAXB on Glassfish, and I've
> run into a bit of a snag serializing a class that uses generics. I need to
> return XML to an ExtJS paginated grid in the following format:
>
> <countedCollection>
> <totalCount>202</totalCount>
> <record version="1">
> <id>25</id>
> <name>Test Client 1</name>
> <baseTag>0025</baseTag>
> <clientStatus>
> <id>1</id>
> <description>Active</description>
> </clientStatus>
> </record>
> <record version="1">
> <id>26</id>
> <name>Test Client 2</name>
> <baseTag>0026</baseTag>
> <clientStatus>
> <id>1</id>
> <description>Active</description>
> </clientStatus>
> </record>
> </countedCollection>
>
> The names are fungible, but the imperative thing is that there be a total
> record count and a list of records. JAXB serializes collections nicely
> enough, and if I return a collection filled with JPA entities from a Jersey
> @GET method, JAXB will serialize the collection, and then Jersey will
> happily shuttle it across the wire. Rather than declare a new class for
> each JPA type, I wrote the following class to encapsulate both the
> collection and a total records count using generics:
>
> package com.donotuse.facade;
>
> import java.util.*;
> import javax.xml.bind.annotation.*;
> import com.donotuse.jpa.*;
>
> @XmlRootElement
> //_at_XmlSeeAlso({Client.class})
> public class CountedCollection<T> {
> private static final long serialVersionUID = -1483486849810154904L;
>
> @XmlElement
> private long totalCount;
>
> @XmlElement
> private Vector<T> records;
>
> CountedCollection() {
>
> }
>
> CountedCollection(Collection<T> list, long totalCount) {
> this.records = new Vector<T>();
> this.records.addAll(list);
> this.totalCount = totalCount;
> }
> }
>
>
> The RESTful service calling this code looks like this:
>
> package com.wdru.rest;
>
> import javax.ws.rs.*;
> import javax.ejb.*;
>
> import com.wdru.facade.ClientFacadeRemote;
> import com.wdru.facade.ClientStatusFacadeRemote;
> import com.wdru.facade.CountedCollection;
> import com.wdru.jpa.Client;
> import com.wdru.jpa.ClientStatus;
>
> @Path("/client")
> @Produces("application/xml")
> public class ClientRest {
> @EJB
> private ClientFacadeRemote cf;
>
> @EJB
> private ClientStatusFacadeRemote csf;
>
> public ClientRest() {
>
> }
> @GET
>
> public CountedCollection<Client> doGet(@QueryParam("dir") String
> sort_dir,
>
> @QueryParam("sort") String sort_field,
>
> @DefaultValue("0") @QueryParam("start") Integer start,
>
> @DefaultValue("0") @QueryParam("limit") Integer limit) throws
> Exception {
> String sd = null;
>
> if (sort_dir!=null) {
> sd = sort_dir.toUpperCase();
> }
>
> return this.cf.readAll(start, limit, sd, sort_field);
> }
> .
> .
> .
>
> All the entities in com.donotuse.jpa are annotated and serialize correctly.
> With the XmlSeeAlso commented out, I get 'javax.xml.bind.JAXBException:
> class com.donotuse.jpa.Client nor any of its super class is known to this
> context.' gracing my log files. When I uncomment the @XmlSeeAlso, it
> serializes just fine, but having to put a reference to every class that
> might use this collection kind of defeats the purpose of using generics in
> the first place.
>
> So my questions is: what is the best way to go about doing this? Is there
> some black magic I can use in the wrapper class that tells JAXB to use type
> T instead of having to specify each type in XmlSeeAlso? Thanks for all
> replies, advice, and flames in advance.
>
> Cheers,
> Pratap
> --
> View this message in context:
> http://www.nabble.com/Using-JAXB-with-generics-tp26054767p26054767.html
> Sent from the java.net - jaxb users mailing list archive at Nabble.com.
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jaxb.dev.java.net
> For additional commands, e-mail: users-help_at_jaxb.dev.java.net
>
>