Marshal / Un Marshal List of objects in Jersey JAX-RS using JAXB

Good morning. This morning as I go through the Jersey Entity providers MessageBodyReader

and MessageBodyWriter

I am facing the following problem.

I want to write a resource method and client that returns a list of custom objects and the media type is application/xml

. So I would like to use JAXB (I'm new to JAXB). I was able to achieve this by writing my own extended MessageBodyReader

and MessageBodyWriter

. But I am afraid of the way I follow. Just see how I have implemented:

Resource method:

@Path("productlist/xml")
@GET
public RetObjects getProductsXml(){
    List<Product> pList = new ArrayList<Product>();
    pList.add(new Product("1","Dell latitude E6000",2900,500));
    pList.add(new Product("2","Xperia Z2",549,400));
    RetObjects obj = new RetObjects();
    obj.setObject(pList);
    return obj;
}

      

My custom objects:

@Entity
@Table (name="PRODUCT")
@XmlRootElement(name="product")
public class Product {

    @Id
    @Column(name = "CODE")
    private String code;
    ...
    // rest of the fields, constructors, getters and setters
 }

      

The object that wraps my custom object list:

 @XmlRootElement(name = "products")
 @XmlAccessorType (XmlAccessType.FIELD)
 public class RetObjects {

     @XmlElement(name = "product")
     private List<Product> object = null;

     public List<Product> getObject() {
         return object;
     }

     public void setObject(List<Product> object) {
         this.object = object;
     }
 }

      

MessageBodyReader/Writer

are straight forward using Jaxb unmarshaller and marshaller over the object RetObjects

.

With this implementation, it works fine as expected and I can get RetObjects

the Product listing completion perfectly fine on the client.

My question here is that instead of my product list in an intermediate object, RetObjects

in my case, I could not marshal and redirect the product list right away. If I want to write another service that returns a list of orders, I need to wrap this with another intermediate object. What is the correct approach to achieve this? How could I do this without intermediate objects?

+1


source to share


1 answer


The first

You don't need yours MessageBodyWriter/Reader

. Jersey / JAX -RS alread has standard support for this. I would stick with the default unless you have a really good reason to hack.

Second

We don't need a shell, you can just return it GenericEntity

. This will automatically wrap items in a multiple wrapper element, i.e. <product>

<products>

.

List<Product> list = new ArrayList<>();
GenericEntity<List<String>> entity = new GenericEntity<List<Product>>(list) {};
Response response = Response.ok(entity).build();

      

To accept a body in a resource method, you just need to accept it List<Product>

as an argument. He will accept<products><product/><product/></products>




UPDATE

To get List<Product>

client side, we have to use GenericType

. Se this post .

Jersey 1

WebResource resource = client.resource("...");
List<Product> products = resource.get(new GenericType<List<Product>>(){});

      

Jersey 2 / JAX-RS 2

Response response = ...
List<Product> products = response.readEntity(new GenericType<List<Product>>(){});

      

+5


source







All Articles