santisan
santisan

Reputation: 149

Passing multiple xml objects to jax-rs service

I'm using JAX-RS Jersey and JAXB on my server code to implement services, which I consume from an Android app. I already have the services returning my custom objects in xml format and I can unmarshal them just fine on the client side. Now I want to send my custom objects from the client to the server in xml, I wrote a simple test but it fails with error 400. This is the service:

@POST
@Path("/test")
@Produces(MediaType.TEXT_PLAIN)
@Consumes(MediaType.APPLICATION_XML)
public String test(List<Client> clientList, Client client) {
    //do something with clientList and client
    return response;
}

This is the xml I send in the request body:

<clientList>
    <client name="" phone="" address="" />        
    <client name="" phone="" address="" />        
</clientList>
<client name="" phone="" address="" />

And here is the client code:

HttpPost httpPost = new HttpPost(url);                
httpPost.addHeader("Accept", "text/plain");
httpPost.setHeader("Content-Type", "application/xml");
httpPost.setEntity(new StringEntity(xmlFromAbove, HTTP.UTF_8));
HttpResponse response = androidHttpClient.execute(httpPost);

If I only put one parameter in the service it works fine, but with more than one it seems that JAXB doesn't know how to unmarshall them. Do I have to wrap all the parameters I need in one custom object, or is there simpler way to do it?

I also tried passing the xml strings as FormParams and using the following code to unmarshal it

JAXBContext jc = JAXBContext.newInstance(Client.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();            
List<Client> clients = 
    (List<Client>)unmarshaller.unmarshal(new StringReader(clientListXml));

But it didn't work either, it throws

javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"clients").  
    Expected elements are <{}client>

When I return a List from the service, jaxb marshalls it correctly, without having to wrap the list in a custom object. Do I have to wrap it anyway in order to do the unmarshalling?

Upvotes: 2

Views: 1529

Answers (1)

Martin Matula
Martin Matula

Reputation: 7979

Do I have to wrap all the parameters I need in one custom object,

Yes, that would be one option.

or is there simpler way to do it?

Not simpler, but you could also use multipart media type to send a request entity consisting of several parts - look at the javadoc of the jersey-multipart module for more info (http://jersey.java.net/nonav/apidocs/latest/jersey/contribs/jersey-multipart/index.html)

When I return a List from the service, jaxb marshalls it correctly, without having to wrap the list in a custom object.

That's because Jersey wraps it for you. If you are unmarshalling the list manually, you have to wrap it yourself.

Upvotes: 4

Related Questions