在XmlAdapter中获取当前主机

时间:2013-07-31 11:40:08

标签: java jaxb jersey jax-rs xmladapter

有没有办法在XmlAdapter中检索当前的基本URI?或者这通常是如何实现的?

public class Service{
...
    @GET
    public MyEntity getEntity() {
        return em.find(MyEntity.class, "dummy");
    }
...
}


@XmlRootElement(name = "myEntity")
public class MyEntity {

    @XmlJavaTypeAdapter(MyAdapter.class)
    private Entity2 entity2Ref;
...

}



public class MyAdapter extends XmlAdapter<Entity2Ref, Entity2> {

// Is NULL but shold be injected with host URI
@Context
UriInfo uri;

...

}

1 个答案:

答案 0 :(得分:2)

以下是如何完成此操作的完整示例:

XML响应

下面我将演示如何获得以下响应:address元素中的URI通过知道XmlAdapter的{​​{1}}放入。

UriInfo

Java模型

以下是我将用于此示例的Java模型。

<强>客户

默认情况下,<?xml version="1.0" encoding="UTF-8"?> <customer id="1"> <name>Jane Doe</name> <address>http://localhost:9999/address/123</address> </customer> 类的内容将在Address元素下编组。我们将使用customer为此执行特殊处理。

XmlAdapter

<强>地址

import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

@XmlRootElement
@XmlType(propOrder={"name", "address"})
public class Customer {

    private int id;
    private String name;
    private Address address;

    @XmlAttribute
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @XmlJavaTypeAdapter(AddressAdapter.class)
    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

}

XmlAdapter

以下是我们将使用的import javax.xml.bind.annotation.XmlAttribute; public class Address { private int id; @XmlAttribute public int getId() { return id; } public void setId(int id) { this.id = id; } } 。请注意它如何从XmlAdapter获取用于构建AddressResource的信息。它需要一个URI,这使它成为有状态的。我们需要在UriInfo上设置此XmlAdapter的实例,以使一切正常运行。

Marshaller

JAX-RS服务

在此示例中,有两个服务,一个用于import javax.ws.rs.core.*; import javax.xml.bind.annotation.adapters.XmlAdapter; public class AddressAdapter extends XmlAdapter<String, Address> { private UriInfo uriInfo; public AddressAdapter() { } public AddressAdapter(UriInfo uriInfo) { this.uriInfo = uriInfo; } @Override public Address unmarshal(String v) throws Exception { // TODO Auto-generated method stub return null; } @Override public String marshal(Address v) throws Exception { if(null == uriInfo) { return ""; } UriBuilder builder = UriBuilder.fromResource(AddressResource.class); System.out.println(uriInfo.getAbsolutePath().getHost()); builder.scheme(uriInfo.getAbsolutePath().getScheme()); builder.host(uriInfo.getAbsolutePath().getHost()); builder.port(uriInfo.getAbsolutePath().getPort()); builder.path(AddressResource.class, "get"); return builder.build(v.getId()).toString(); } } ,另一个用于Address

<强> AddressResource

Customer

<强> CustomerResource

由于我们有一个有状态import javax.ws.rs.*; import javax.ws.rs.ext.Provider; @Provider @Path("/address") public class AddressResource { @GET @Path("{id}") public Address get(@PathParam("id") int id) { Address address = new Address(); address.setId(id); return address; } } ,我们不能只通过默认绑定来利用JAXB。相反,我们可以通过XmlAdapter

访问JAXB
StreamingOutput

StreamingOutput

import javax.ws.rs.*;
import javax.ws.rs.core.*;
import javax.ws.rs.ext.Provider;
import javax.xml.bind.*;

@Provider
@Path("/customer")
public class CustomerResource {

    private JAXBContext jaxbContext;

    public CustomerResource() {
        try {
            jaxbContext = JAXBContext.newInstance(Customer.class);
        } catch (JAXBException e) {
            // TODO - Handle Exception
        }
    }

    @GET
    @Path("{id}")
    @Produces(MediaType.APPLICATION_XML)
    public StreamingOutput get(@Context UriInfo uriInfo, @PathParam("id") int id) {
        Customer customer = new Customer();
        customer.setId(id);
        customer.setName("Jane Doe");

        Address address = new Address();
        address.setId(123);
        customer.setAddress(address);

        return new MyStreamingOutput(jaxbContext, customer, uriInfo);
    }

}