RESTEasy服务,用于生成xml并返回给出空集合的JAXB对象的数组/列表



我正在试用RESTEasy Web服务。我编写了一个简单的服务来返回JAXBCustomer对象的List,并期望返回的xml是collection标记下的Customer标记的集合。但我得到的是<Collection/>,意思是一个空集合。

我的代码是:

客户服务

@Path("/customers")
public class CustomerService {
List<Customer> customersList = new ArrayList<Customer>();
public CustomerService() {
    customersList.add(new Customer(.....)); //Creating Customers using parametarized Cunstructor
    customersList.add(new Customer(.....));
    customersList.add(new Customer(.....));
    customersList.add(new Customer(.....));
    customersList.add(new Customer(.....));
}
@GET
@Produces("application/xml")
@Path("/xml/list")  
public List<Customer> getAllCustomersList(){
    return customersList; //nonEmpty list of Customers
}
}

客户(JAXB对象)

@XmlRootElement
public class Customer {
private String customerId;
private String name;
private String address;
private int age;
public Customer() { }
public Customer(String customerId, String name, String address, int age) {
    super();
    this.customerId = customerId;
    this.name = name;
    this.address = address;
    this.age = age;
}
@XmlAttribute
public String getCustomerId() {
    return customerId;
}
public void setCustomerId(String customerId) {
    this.customerId = customerId;
}
@XmlElement
public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
@XmlElement
public String getAddress() {
    return address;
}
public void setAddress(String address) {
    this.address = address;
}
@XmlElement
public int getAge() {
    return age;
}
public void setAge(int age) {
    this.age = age;
}
    }

我可以通过这项服务获得单个客户,它运行得很好:

@GET
@Produces("application/xml")
@Path("/xml/{id}")  
public Customer getCustomer(@PathParam("id") String customerId){
    for(Customer customer: customersList){
        if(customerId.equals(customer.getCustomerId()))
            return customer;
    }
    return null;
    }

我已经使服务成为singleton,所以列表不是空的,这是肯定的。甚至我也调试了代码以确认列表不是空的。我也试过用数组,同样的情况也发生了。

以下是我正在阅读的内容:http://docs.jboss.org/resteasy/docs/2.3.0.GA/userguide/html/Built_in_JAXB_providers.html#JAXB_Collections

我正在使用

  • WebSphere Application Server 8.0
  • RESTEasy 2.2.3GA

我能够通过进行以下更改使序列化与您的客户POJO一起工作:

  • @XmlElement注释移动到字段
  • 添加了@XmlAccessorType(XmlAccessType.FIELD)注释,告诉JAXB按字段绑定并忽略getters/ssetter

方法:

@GET
@Path("/customers")
@Produces(MediaType.APPLICATION_XML)
public List<Customer> getCustomer()
{
    List<Customer> customers = new ArrayList<Customer>();
    customers.add(new Customer("1", "customer1", "some address 1", 20));
    customers.add(new Customer("2", "customer2", "some address 2", 45));
    customers.add(new Customer("3", "customer3", "some address 3", 36));
    return customers;
}

客户POJO:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement
public class Customer 
{
    @XmlAttribute
    private String customerId;
    @XmlElement
    private String name;
    @XmlElement
    private String address;
    @XmlElement
    private int age;
    public Customer()
    {
    }
    public Customer(String customerId, String name, String address, int age)
    {
        this.customerId = customerId;
        this.name = name;
        this.address = address;
        this.age = age;
    }
    public String getCustomerId() 
    {
        return customerId;
    }
    public void setCustomerId(String customerId) 
    {
        this.customerId = customerId;
    }
    public String getName() 
    {
        return name;
    }
    public void setName(String name) 
    {
        this.name = name;
    }
    public String getAddress()
    {
        return address;
    }
    public void setAddress(String address)
    {
        this.address = address;
    }
    public int getAge() 
    {
        return age;
    }
    public void setAge(int age) 
    {
        this.age = age;
    }
}

输出XML:

<?xml version="1.0" encoding="UTF-8"?>
<collection>
    <customer customerId="1">
        <name>customer1</name>
        <address>some address 1</address>
        <age>20</age>
    </customer>
    <customer customerId="2">
        <name>customer2</name>
        <address>some address 2</address>
        <age>45</age>
    </customer>
    <customer customerId="3">
        <name>customer3</name>
        <address>some address 3</address>
        <age>36</age>
    </customer>
</collection>

如果要更改包装元素的名称,该怎么办

如果您不喜欢用collection元素包装返回的xml列表,并且希望更改名称,则可以将@Wrapped注释添加到您的资源方法中,如下所示:

@GET
@Path("/customers")
@Produces(MediaType.APPLICATION_XML)
@Wrapped(element = "customers")
public List<Customer> getCustomer()
{
    List<Customer> customers = new ArrayList<Customer>();
    customers.add(new Customer("1", "customer1", "some address 1", 20));
    customers.add(new Customer("2", "customer2", "some address 2", 45));
    customers.add(new Customer("3", "customer3", "some address 3", 36));
    return customers;
}

这将客户列表封装在customers元素中,而不是collection中。

<?xml version="1.0" encoding="UTF-8"?>
<customers>
    <customer customerId="1">
        <name>customer1</name>
        <address>some address 1</address>
        <age>20</age>
    </customer>
    <customer customerId="2">
        <name>customer2</name>
        <address>some address 2</address>
        <age>45</age>
    </customer>
    <customer customerId="3">
        <name>customer3</name>
        <address>some address 3</address>
        <age>36</age>
    </customer>
</customers>

最新更新