users@jaxb.java.net

Using JAXB with generics

From: Pratap Singh <p.singh11972_at_gmail.com>
Date: Sun, 25 Oct 2009 22:30:23 -0700 (PDT)

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.