users@jersey.java.net

parsing JSON with Arrays using Jettison

From: Dhanush Gopinath <dhanush.gopinath_at_altair.com>
Date: Fri, 12 Nov 2010 18:14:09 +0530

Hi,

 

I have a REST service which has a get method and post method. Get method
returns a JAXBElement< of some object> which contains an Array of other
Objects. Where as POST method receives the same JAXBElement< of some
object> with an Array of other Objects. I am using Jettison mapping as
the JSONConfiguration.

 

The GET operation works fine and I get the correct JSON values when I
accept JSON. But when posting the same JSON back using the POST method,
it doesn't populate the Array of Objects inside the JAXBElement.

 

The POST works fine when the array size is 1; if there is more than one
element then the JAXBElement always has null as the Array value.

 

Any idea why this is happening.

 

Here are my REST API's

 

@GET

      @Path("getVehicles")

      @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})

      public JAXBElement<VehicleObjList> getVehicles()

      {

            CarType car = new CarType();

            car.setMake("Punto");

            car.setId(1);

            car.setModel("2010");

            car.setPrice(200);

            

            BusObject bo = new BusObject();

            bo.setBuscompany("Lyland");

            bo.setBusName("ashok");

            bo.setYear("789");

            

            CarObject co = new CarObject();

            co.setCompany("Fiat");

            co.setName("Punto");

            co.setYear("789");

            

            VehicleObj vo = new VehicleObj();

            vo.setBusObj(bo);

            vo.setCar(car);

            vo.setCarObj(co);

            

            

            VehicleObj vo2 = new VehicleObj();

            vo2.setBusObj(bo);

            vo2.setCar(car);

            vo2.setCarObj(co);

            

            VehicleObj vo3 = new VehicleObj();

            vo3.setBusObj(bo);

            vo3.setCar(car);

            vo3.setCarObj(co);

            VehicleObjList list = new VehicleObjList();

            list.getVehicle().add(vo);

            list.getVehicle().add(vo2);

            list.getVehicle().add(vo3);

            

            ObjectFactory of = new ObjectFactory();

            return of.createVehicleList(list);

      }

 

      @POST

      @Path("putVehicles")

      @Produces(MediaType.TEXT_PLAIN)

      @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})

      public String putVehicles(JAXBElement<VehicleObjList> element)

      {

      

            VehicleObjList list = element.getValue();

            List<VehicleObj> vehicle = list.getVehicle(); ----> THIS
RETURNS NULL

            return "true";

      }

 

I have to use JAXBElement as the return types and parameters since the
JAXB Binding classes already exists and we cannot edit the schema to add
some @XmlRootElement's as this Binding classes are used in SOAP services
also.

 

Please let me know if you have come across this issue and if so pls
suggest the solution you had to work around.

 

Here is my ContextResolver implementation

 

@Provider

public final class JAXBContextResolver implements
ContextResolver<JAXBContext> {

 

      private final JAXBContext context;

 

      private final Set<Class> types;

 

      private final Class[] cTypes = { VehicleObjList.class,
VehicleObj.class, CarObject.class,

                  CarType.class, BusObject.class };

 

      public JAXBContextResolver() throws Exception {

            this.types = new HashSet(Arrays.asList(cTypes));

 

            Map<String, String> ns2json = new HashMap<String, String>();

            ns2json.put("http://www.theserverlabs.com/namespaces/cars",
"1");

            ns2json.put("http://www.theserverlabs.com/namespaces/bus",
"2");

                        

            this.context = new
JSONJAXBContext(JSONConfiguration.mappedJettison()

                        .xml2JsonNs(ns2json).build(), cTypes);

            

            

            

      }

 

      public JAXBContext getContext(Class<?> objectType) {

            return (types.contains(objectType)) ? context : null;

      }

}

 

Thanks & Regards

Dhanush Gopinath