Reputation:
My REST
service outputs @Produces(MediaType.APPLICATION_XML)
. This is converted from:
ArrayList<CoffeeOrder> orders = new ArrayList<CoffeeOrder>();
GenericEntity<ArrayList<CoffeeOrder> > entity = new GenericEntity<ArrayList<CoffeeOrder> >(orders) {};
....
return Response.status(Response.Status.OK).entity(entity).build();
Example
:
<coffeeOrders>
<coffeeOrder>
<id>2</id>
<links>http://localhost:9080/cs9322.ass2/rest/coffee/2</links>
<links>http://localhost:9080/cs9322.ass2/rest/payment/2</links>
</coffeeOrder>
<coffeeOrder>
<id>1</id>
<links>http://localhost:9080/cs9322.ass2/rest/coffee/1</links>
<links>http://localhost:9080/cs9322.ass2/rest/payment/1</links>
</coffeeOrder>
In my client
, I want to call this service and save the response as an ArrayList<CoffeeOrder>
.
CoffeeOrder
looks something like this:
public class CoffeeOrder {
private String id;
private ArrayList<String> links = new ArrayList<String>();
...
}
Is there a way that I can fill this object with the response from the REST
request?
Thank you for your help!
Upvotes: 0
Views: 1317
Reputation: 208944
My suggestion is to use JAXB annotations. As noted from Jersey Tutorial, " Jersey contains default support for entity providers that can serialize JAXB beans into XML"
So you could create a CoffeeOrders
class, that holds a List<CoffeeOrder>
. Something like
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class CoffeeOrders {
@XmlElement(name = "coffeOrder")
protected List<CoffeeOrder> coffeeOrders;
// GETTER and SETTERS
public void addCoffeeOrder(CoffeeOrder coffeeOrder) {
if (coffeeOrders == null) {
coffeeOrders = new ArrayList<>();
}
coffeeOrders.add(coffeeOrder);
}
}
Your response could simply be
CoffeeOrders orders = new CoffeeOrders();
// add CoffeeOrder(s) to list in orders
return Response.ok(orders).build();
As far as the <links>
go, it seems you are trying to implements some HATEOAS format. I'd suggest maybe using the Link
class to create links. You can have a List<Link>
in the CoffeeOrder
class.
@XmlAccessorType(XmlAccessType.FIELD)
public class CoffeeOrder {
@XmlElement
protected String id;
@XmlElement(name = "link")
@XmlJavaTypeAdapter(Link.JaxbAdapter.class)
protected List<Link> links;
// GETTERS and SETTERS
}
And (not so great) example of a response could be something like
@Path("/coffee")
public class CoffeeResource {
@GET
@Produces(MediaType.APPLICATION_XML)
public Response getCoffeOrders(@Context UriInfo uriInfo) {
UriBuilder builder = uriInfo.getBaseUriBuilder();
CoffeeOrders orders = new CoffeeOrders();
CoffeeOrder order = new CoffeeOrder();
order.setId("1");
List<Link> links = new ArrayList<>();
URI coffee = builder.clone().path("coffee").path("1").build();
Link coffeeLink = Link.fromUri(coffee).rel("coffee1")
.type(MediaType.APPLICATION_XML).build();
links.add(coffeeLink);
URI payment = builder.clone().path("payment").path("1").build();
Link paymentLink = Link.fromUri(coffee).rel("payment1")
.type(MediaType.APPLICATION_XML).build();
links.add(coffeeLink);
order.setLinks(links);
orders.addCoffeeOrder(order);
return Response.ok(orders).build();
}
}
Receiving the Response
might look something like
@Test
public void testGetIt() throws Exception {
Response response = target.path("coffee").request().get();
CoffeeOrders order = response.readEntity(CoffeeOrders.class);
response.close();
JAXBContext context = JAXBContext.newInstance(CoffeeOrders.class);
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(order, System.out);
}
And the result
<coffeeOrders>
<coffeOrder>
<id>1</id>
<link href="http://localhost:8080/myapp/coffee/1" rel="coffee1" type="application/xml"/>
<link href="http://localhost:8080/myapp/coffee/1" rel="coffee1" type="application/xml"/>
</coffeOrder>
</coffeeOrders>
To receive a POST with the CoffeeOrders
object, just use the same xml accept type. The Jersey runtime will parse the xml for you, based on the JAXB annotations you provided.
Some resources:
Upvotes: 1