public class Client {
private Integer idclientinfo;
private String clientname;
private String tel1;
private String tel2;
private String fax;
private String email;
private String address;
private String city;
private String province;
private String country;
private String mailaddress;
private String owner;
private String corporation_types;
private String switchboard;
private List> childs = new ArrayList>();
private List groups = new ArrayList();
}
假设我们有一个方法 public Client getClient(){
// return a Client instance;
}
方法返回的是Client的一个实例 JAXB会找到你定义的Client类 ,然后一层层的向复杂类型里面去识别,将复杂类型 分解为一个个的简单类型
对于Integer String 这些基础类型JAXB 已经能为我们很好的处理
对于List
对于List> 虽然 childs 是一个具体的ArrayList
>();
但是childs里面还嵌套了一个LIst
List is a interface JAXB can't handle it
因些我们有如下三种方法去处理
方法1: 用具体的类去wrapper 内部的 List
改写为
public class Type {
private List
List childs = new ArrayList();
方法2:抛弃多态直接用实现类
List> childs = new ArrayList>();
方法3:用XmlAdapter 手动处理
新创建一个类 MyXmlAdapter 让他继承自 XmlAdapter
因为JAXB不支持将HashMap 或其他非 JavaBean 类 自然映射到xml表示形式,这样就要定义一个适配器使用java类型适应自定义编组.一般有两步:
1>. 编写一个类继承XmlAdapter,以实现此抽象类的适配器。
2>. 安装使用注释XmlJavaTypeAdapter 的适配器。
类XmlAdapter的说明:
类 XmlAdapter
BoundType - JAXB 不知道如何处理的一些类型。编写一个适配器,以便允许通过 ValueType 将此类型用作内存表示形式。
ValueType - JAXB 无需其他操作便知道如何处理的类型。
2个参数目的就是将帮你处理的BoundType通过一定算法处理变成可以处理的ValueType
其两个抽象方法:
marshal(...):编组过程中,JAXB 绑定框架调用 XmlAdapter.marshal(..) 将 bound 类型修改为 value 类型,然后将 value 类型编组为 XML 表示形式。
unmarshal(...):解组过程中,JAXB 绑定框架首先将 XML 表示形式解组为 value 类型,然后调用 XmlAdapter.unmarshal(..) 将 value 类型修改为 bound 类型。
常用的几个注释说明:
a.@XmlJavaTypeAdapter 注释可以与下列编程元素一起使用: JavaBean 属性 、字段、参数 、包 、XmlJavaTypeAdapters 内部的元素 。用来表示使用实现XmlAdapter的适配器,告诉其如何如何转换。
b. @XmlType 注释可以与以下程序元素一起使用:顶层类、枚举类型 。表示将类或枚举类型映射到 XML 模式类型。
c. @XmlAccessorType 注释可以与以下程序元素一起使用:包、顶层类。表示控制默认情况下是否对字段或 Javabean 属性进行序列化。
@XmlAccessorType(XmlAccessType.FIELD)
FIELD :JAXB 绑定类中的每个非静态、非瞬态字段将会自动绑定到 XML,除非由XmlTransient 注释。
d. @XmlElement 注释可以与以下程序元素一起使用: JavaBean 属性、非 static、非 transient 字段 、XmlElements 中的程序元素 。表示将 JavaBean 属性映射到派生于属性名称的 XML 元素。
如:将User接口转化的适配器类:UserAdapter:
import javax.xml.bind.annotation.adapters.XmlAdapter;
/*XmlAdapter
* BoundType - JAXB 不知道如何处理的一些类型。编写一个适配器,以便允许通过 ValueType 将此类型用作内存表示形式。
ValueType - JAXB 无需其他操作便知道如何处理的类型。
*/
public class UserAdapter extends XmlAdapter {
/*marshal表示要将user类型编组为UserImpl类型*/
public UserImpl marshal(User v) throws Exception {
if (v instanceof UserImpl) {
return (UserImpl)v;
}
return new UserImpl(v.getUsername(),v.getPassword());
}
/*marshal表示要将UserImpl类型解组为具体的类User*/
public User unmarshal(UserImpl v) throws Exception {
return v;
}
}
将Map转化的适配器类:UserMapAdapter.java 和UserMap.java
@XmlType(name = "UserMap")
@XmlAccessorType(XmlAccessType.FIELD)
public classUserMap {
@XmlElement(nillable = false, name = "entry")
List entries = new ArrayList();
/**
* @return the entries
*/
public List getEntries() {
return entries;
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "IdentifiedUser")
static class UserEntry {
//Map keys cannot be null
@XmlElement(required = true, nillable = false)
Integer id;
User user;
public void setId(Integer k) {
id = k;
}
public Integer getId() {
return id;
}
public void setUser(User u) {
user = u;
}
public User getUser() {
return user;
}
}
}
public classUserMapAdapter extends XmlAdapter> {
@Override
public UserMap marshal(Map v) throws Exception {
UserMap userMap=new UserMap();
for (Map.Entry e : v.entrySet()) {
UserMap.UserEntry iue = new UserMap.UserEntry();
iue.setUser(e.getValue());
iue.setId(e.getKey());
userMap.getEntries().add(iue);
}
return userMap;
}
@Override
public Map unmarshal(UserMap v) throws Exception {
Map map = new LinkedHashMap();
for (UserMap.UserEntry e : v.getEntries()) {
map.put(e.getId(), e.getUser());
}
return map;
}
}