如何使用JAXB包装子列表

14

在尝试使用jaxb 2.2.6映射一个客户->订单1:n关系时,我希望能够获得包含订单列表的独立节点"orders"。

当前的结果是:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
    <Customer>
       <id>100</id>
       <name>John Doe</name>
       <orders>
         <address>100 main street, smalltown, pa</address>
         <orderid>1100</orderid>
       </orders>
      <orders>
         <address>5 broadway, ny, ny</address>
         <orderid>1200</orderid>
       </orders> 
    </Customer>

但我想获得:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
    <Customer>
       <id>100</id>
       <name>John Doe</name>
       <orders>
         <order>
           <address>100 main street, smalltown, pa</address>
           <orderid>1100</orderid>
         </order>
         <order>
            <address>5 broadway, ny, ny</address>
            <orderid>1200</orderid>
         </order>
       </orders> 
    </Customer>

为了得到这个结果,需要做哪些修改?

相关源代码包括:

  • 客户端接口
  • CustomerJaxbDao 实现
  • 订单接口
  • OrderJaxbDao 实现
  • TestCustomerWrite Junit4 测试用例

并且使用了这个 jaxb 实现:

            <!-- JAXB -->
    <dependency>
        <groupId>com.sun.xml.bind</groupId>
        <artifactId>jaxb-impl</artifactId>
        <version>2.2.6</version>
    </dependency>

客户接口:

/**
 * Copyright (C) 2011-2012 BITPlan GmbH
 * 
 * http://www.bitplan.com
 *
 * generated: 2012-10-15 15:12 with smartGENERATOR
 */
package com.bitplan.testentity;
import java.util.List;
import com.bitplan.testentity.Order;


/**
 * interface for Customer
 */
public interface Customer {
    // >>>{interface}{Customer}{Customer}
    // no implementation yet !!!
    // <<<{interface}{Customer}{Customer}
  /**
   * getter for name
   * @return name
   */
  public String getName();

  /**
   * setter for name
   * @param pname - new value for name
   */
  public void setName(String pname);

  /**
   * getter for id
   * @return id
   */
  public long getId();

  /**
   * setter for id
   * @param pid - new value for id
   */
  public void setId(long pid);

  /**
   * getter for orders
   * @return orders
   */
  public List<Order> getOrders();

  /**
   * setter for orders
   * @param porders - new value for orders
   */
  public void setOrders(List<Order> porders);

} // Customer

订单界面:

/**
 * Copyright (C) 2011-2012 BITPlan GmbH
 * 
 * http://www.bitplan.com
 *
 * generated: 2012-10-15 at 23:59 with smartGENERATOR
 */
package com.bitplan.testentity;

/**
 * interface for Order
 */
public interface Order {
    // >>>{interface}{Order}{Order}
    // no implementation yet !!!
    // <<<{interface}{Order}{Order}
  /**
   * getter for orderid
   * @return orderid
   */
  public long getOrderid();

  /**
   * setter for orderid
   * @param porderid - new value for orderid
   */
  public void setOrderid(long porderid);

  /**
   * getter for shipping address
   * @return address
   */
  public String getAddress();

  /**
   * setter for shipping address
   * @param paddress - new value for shipping address
   */
  public void setAddress(String paddress);

} // Order

CustomerJaxbDao实现

/**
 * Copyright (C) 2011-2012 BITPlan GmbH
 * 
 * http://www.bitplan.com
 *
 * generated: 2012-10-15 at 23:51 with smartGENERATOR
 */
package com.bitplan.testentity.jaxb;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlElement;

import com.bitplan.testentity.Order;
import com.bitplan.testentity.Customer;

import java.util.List;
import java.util.ArrayList;

/**
 * JaxB Data access object for Customer
 * Entity: Customer for container testentity
 * Table: Customer
 */
@XmlRootElement(name="Customer")
public class CustomerJaxbDao implements Customer {
  /**
   * name
   */
  private String name;

  /**
   * id
   */
  private long id;

  /**
   * orders
   */
  private List<Order> orders=new ArrayList<Order>();

  /**
   * getter for name
   * @return name
   */
  @XmlElement(name="name")
  public String getName() { return name; };

  /**
   * setter for name
   * @param pname - new value for name
   */
  public void setName(String pname) { name=pname; };

  /**
   * getter for id
   * @return id
   */
  @XmlElement(name="id")
  public long getId() { return id; };

  /**
   * setter for id
   * @param pid - new value for id
   */
  public void setId(long pid) { id=pid; };

  /**
   * getter for orders
   * @return orders
   */
  @XmlElement(name="orders", type=OrderJaxbDao.class)
  public List<Order> getOrders() { return orders; };

  /**
   * setter for orders
   * @param porders - new value for orders
   */
  public void setOrders(List<Order> porders) { orders=porders; };


} // CustomerJaxbDao

OrderJaxbDao实现

/**
 * Copyright (C) 2011-2012 BITPlan GmbH
 * 
 * http://www.bitplan.com
 *
 * generated: 2012-10-15 with smartGENERATOR
 */
package com.bitplan.testentity.jaxb;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlElement;
import com.bitplan.testentity.Order;


/**
 * JaxB Data access object for Order
 * Entity: Order for container testentity
 * Table: Order
 */
@XmlRootElement(name="Order")
public class OrderJaxbDao implements Order {
  /**
   * orderid
   */
  private long orderid;

  /**
   * shipping address
   */
  private String address;

  /**
   * getter for orderid
   * @return orderid
   */
  @XmlElement(name="orderid")
  public long getOrderid() { return orderid; };

  /**
   * setter for orderid
   * @param porderid - new value for orderid
   */
  public void setOrderid(long porderid) { orderid=porderid; };

  /**
   * getter for shipping address
   * @return address
   */
  @XmlElement(name="address")
  public String getAddress() { return address; };

  /**
   * setter for shipping address
   * @param paddress - new value for shipping address
   */
  public void setAddress(String paddress) { address=paddress; };


} // OrderJaxbDao

测试客户编写的Junit4测试用例

package com.bitplan.storage.jaxb;

import static org.junit.Assert.*;

import java.io.StringWriter;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;

import org.junit.Test;

import com.bitplan.testentity.Customer;
import com.bitplan.testentity.Order;
import com.bitplan.testentity.jaxb.CustomerJaxbDao;
import com.bitplan.testentity.jaxb.OrderJaxbDao;

/**
 * 
 * @author wf
 *
 */
public class TestCustomerWrite {

    @Test
    public void test() throws JAXBException {
        Customer customer=new CustomerJaxbDao();
        customer.setId(100);
        customer.setName("John Doe");
        long orderid=1000;
        String[] addresses={"100 main street, smalltown, pa","5 broadway, ny, ny"};
        for (String address:addresses) {
            Order order=new OrderJaxbDao();
            order.setAddress(address);
            order.setOrderid(orderid+=100);
            customer.getOrders().add(order);
        }
        JAXBContext jaxbContext = JAXBContext.newInstance(CustomerJaxbDao.class);
        Marshaller jaxbMarshaller = jaxbContext.createMarshaller();

        // output pretty printed
        jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

        StringWriter sw=new StringWriter();
        jaxbMarshaller.marshal(customer, sw);
        System.out.println(sw);

    }

}
3个回答

17

相比于

/**
 * getter for orders
 * @return orders
 */
@XmlElement(name="orders", type=OrderJaxbDao.class)
public List<Order> getOrders() { return orders; };
你需要。
/**
 * getter for orders
 * @return orders
 */
@XmlElement(name="order", type=OrderJaxbDao.class)
@XmlElementWrapper(name="orders")
public List<Order> getOrders() { return orders; };

@XmlElementWrapper 的名称是包装元素的名称(orders),@XmlElement 的名称是包装器内每个条目元素的名称(order)。


8
这似乎可以解决问题:
  @XmlElementWrapper(name="orders")
  @XmlElement(name="order", type=OrderJaxbDao.class)
  public List<Order> getOrders() { return orders; };

improved CustomerJaxbDao

/**
 * Copyright (C) 2011-2012 BITPlan GmbH
 * 
 * http://www.bitplan.com
 * 
 * generated: 2012-10-16 12:20 with smartGENERATOR
 */
package com.bitplan.testentity.jaxb;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlElement;
import com.bitplan.testentity.Customer;

import java.util.List;
import com.bitplan.testentity.Order;
import javax.xml.bind.annotation.XmlElementWrapper;
import java.util.ArrayList;

/**
 * JaxB Data access object for Customer
 * Entity: Customer for container testentity
 * Table: Customer
 */
@XmlRootElement(name="Customer")
public class CustomerJaxbDao implements Customer {
  /**
   * name
   */
  private String name;

  /**
   * id
   */
  private long id;

  /**
   * orders
   */
  private List<Order> orders=new ArrayList<Order>();

  /**
   * getter for name
   * @return name
   */
  @XmlElement(name="name")  
  public String getName() { return name; };

  /**
   * setter for name
   * @param pname - new value for name
   */
  public void setName(String pname) { name=pname; };

  /**
   * getter for id
   * @return id
   */
  @XmlElement(name="id")  
  public long getId() { return id; };

  /**
   * setter for id
   * @param pid - new value for id
   */
  public void setId(long pid) { id=pid; };

  /**
   * getter for orders
   * @return orders
   */
  @XmlElementWrapper(name="orders")
  @XmlElement(name="order", type=OrderJaxbDao.class)
  public List<Order> getOrders() { return orders; };

  /**
   * setter for orders
   * @param porders - new value for orders
   */
  public void setOrders(List<Order> porders) { orders=porders; };


} // CustomerJaxbDao

3

听起来你希望在CustomerJaxbDao类中包装订单。

@XmlElementWrapper( name="orders" )
@XmlElement(name="order", type=OrderJaxbDao.class)
public List<Order> getOrders() { return orders; };

也许可以满足你的需求。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接