Jersey客户端将REST调用的响应保存到自定义对象中

时间:2014-10-18 01:41:57

标签: java rest jersey

我的REST服务输出@Produces(MediaType.APPLICATION_XML)。这是从:

转换而来的
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>

在我的client中,我想调用此服务并将回复另存为ArrayList<CoffeeOrder>

CoffeeOrder看起来像这样:

public class CoffeeOrder {

   private String id;

   private ArrayList<String> links = new ArrayList<String>();

   ...
}

有没有办法可以使用REST请求的响应来填充此对象?

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

我的建议是使用JAXB annotations。正如Jersey Tutorial所述,“Jersey包含对可以将JAXB bean序列化为XML的实体提供程序的默认支持”

因此,您可以创建一个CoffeeOrders类,其中包含List<CoffeeOrder>。像

这样的东西
@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);
    }
}

您的回复可能只是

CoffeeOrders orders = new CoffeeOrders();
// add CoffeeOrder(s) to list in orders
return Response.ok(orders).build();

<links>而言,您似乎正在尝试实现某种HATEOAS格式。我建议可以使用Link类来创建链接。您可以在List<Link>课程中拥有CoffeeOrder

@XmlAccessorType(XmlAccessType.FIELD)
public class CoffeeOrder {

    @XmlElement
    protected String id;

    @XmlElement(name = "link")
    @XmlJavaTypeAdapter(Link.JaxbAdapter.class)
    protected List<Link> links;

    // GETTERS and SETTERS
}

并且(不太好)响应的例子可能是

@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();
    }
}

接收Response可能看起来像

@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);
}

结果

<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>

要使用CoffeeOrders对象接收POST,只需使用相同的xml接受类型。 Jersey运行时将根据您提供的JAXB注释为您解析xml。


一些资源: