CXF webservice JAXB 处理复杂数据类型方法
2012-05-15 19:52
543 查看
假定有一个复杂类型如下
假设我们有一个方法 public Client getClient(){
// return a Client instance;
}
方法返回的是Client的一个实例 JAXB会找到你定义的Client类 ,然后一层层的向复杂类型里面去识别,将复杂类型 分解为一个个的简单类型
对于Integer String 这些基础类型JAXB 已经能为我们很好的处理
对于List<String> 他虽然是接口 ,但他的实例groups 是ArrayList<String> ,这是一个具体类,有自己默认的constructor 那个JAXB也可以为我们处理
对于List<List<Object>> 虽然 childs 是一个具体的ArrayList<List<Object>>();
但是childs里面还嵌套了一个LIst<Object> 这是一个接口类型,如果我们不对其进行处理 JAXB会报如下错误
List is a interface JAXB can't handle it
因些我们有如下三种方法去处理
方法1: 用具体的类去wrapper 内部的 List<Object>接口
改写为
这样就把内部的接口List<Object> 给包装成了实际的一个类,这个类里面又维护了一个实际的 child 类型为 ArrayList,child里面又维护了一个实际的Object 他们都不是接口,都是具体的可构造出来的类,并且也保护了多态的特性
方法2:抛弃多态直接用实现类
这样改写的话,从外到内都是具体的类,只不过第二层的List失去了多态的特性只能是一个实际的ArrayLIst
方法3:用XmlAdapter 手动处理
新创建一个类 MyXmlAdapter 让他继承自 XmlAdapter
因为JAXB不支持将HashMap 或其他非 JavaBean 类 自然映射到xml表示形式,这样就要定义一个适配器使用java类型适应自定义编组.一般有两步:
1>. 编写一个类继承XmlAdapter,以实现此抽象类的适配器。
2>. 安装使用注释XmlJavaTypeAdapter 的适配器。
类XmlAdapter的说明:
类 XmlAdapter<ValueType,BoundType>
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:
将Map转化的适配器类:UserMapAdapter.java 和UserMap.java
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<List<Object>> childs = new ArrayList<List<Object>>(); private List<String> groups = new ArrayList<String>(); }
假设我们有一个方法 public Client getClient(){
// return a Client instance;
}
方法返回的是Client的一个实例 JAXB会找到你定义的Client类 ,然后一层层的向复杂类型里面去识别,将复杂类型 分解为一个个的简单类型
对于Integer String 这些基础类型JAXB 已经能为我们很好的处理
对于List<String> 他虽然是接口 ,但他的实例groups 是ArrayList<String> ,这是一个具体类,有自己默认的constructor 那个JAXB也可以为我们处理
对于List<List<Object>> 虽然 childs 是一个具体的ArrayList<List<Object>>();
但是childs里面还嵌套了一个LIst<Object> 这是一个接口类型,如果我们不对其进行处理 JAXB会报如下错误
List is a interface JAXB can't handle it
因些我们有如下三种方法去处理
方法1: 用具体的类去wrapper 内部的 List<Object>接口
改写为
public class Type { private List<Object> child = new ArrayList<Object>(); public List<Object> getChild() { return child; } public void setChild(List<Object> child) { this.child = child; } }
List<Type> childs = new ArrayList<Type>();
这样就把内部的接口List<Object> 给包装成了实际的一个类,这个类里面又维护了一个实际的 child 类型为 ArrayList,child里面又维护了一个实际的Object 他们都不是接口,都是具体的可构造出来的类,并且也保护了多态的特性
方法2:抛弃多态直接用实现类
List<ArrayList<Object>> childs = new ArrayList<ArrayList<Object>>();
这样改写的话,从外到内都是具体的类,只不过第二层的List失去了多态的特性只能是一个实际的ArrayLIst
方法3:用XmlAdapter 手动处理
新创建一个类 MyXmlAdapter 让他继承自 XmlAdapter
因为JAXB不支持将HashMap 或其他非 JavaBean 类 自然映射到xml表示形式,这样就要定义一个适配器使用java类型适应自定义编组.一般有两步:
1>. 编写一个类继承XmlAdapter,以实现此抽象类的适配器。
2>. 安装使用注释XmlJavaTypeAdapter 的适配器。
类XmlAdapter的说明:
类 XmlAdapter<ValueType,BoundType>
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<ValueType,BoundType> * BoundType - JAXB 不知道如何处理的一些类型。编写一个适配器,以便允许通过 ValueType 将此类型用作内存表示形式。 ValueType - JAXB 无需其他操作便知道如何处理的类型。 */ public class UserAdapter extends XmlAdapter<UserImpl, User> { /*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<UserEntry> entries = new ArrayList<UserEntry>(); /** * @return the entries */ public List<UserEntry> 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<UserMap,Map<Integer,User>> { @Override public UserMap marshal(Map<Integer, User> v) throws Exception { UserMap userMap=new UserMap(); for (Map.Entry<Integer, User> 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<Integer, User> unmarshal(UserMap v) throws Exception { Map<Integer, User> map = new LinkedHashMap<Integer, User>(); for (UserMap.UserEntry e : v.getEntries()) { map.put(e.getId(), e.getUser()); } return map; } }
相关文章推荐
- CXF webservice JAXB 处理复杂数据类型方法
- 【WebService】CXF处理javaBean等复合类型以及Map等复杂类型的数据
- 【WebService】CXF处理javaBean等复合类型以及Map等复杂类型的数据
- 【WebService】CXF处理javaBean等复合类型以及Map等复杂类型的数据
- ofbiz的webservice接口提供(4)-支持复杂数据类型方法
- ofbiz的webservice接口提供(4)-支持复杂数据类型方法
- CXF+JAXB处理复杂数据
- android调用webservice复杂数据类型处理
- Android通过ksoap2传递复杂数据类型,服务端为CXF发布的webservice,亲手写的代码
- ofbiz的webservice接口提供(4)-支持复杂数据类型方法
- ofbiz的webservice接口提供(4)-支持复杂数据类型方法
- CXF+JAXB处理复杂数据
- CXF+JAXB处理复杂数据
- 使用CXF开发WebService程序的总结(五):基于Map数据类型处理的的客户端和服务端代码的编写
- ofbiz的webservice接口提供(4)-支持复杂数据类型方法
- "转" CXF+JAXB处理复杂数据
- ofbiz的webservice接口提供(4)-支持复杂数据类型方法
- Android通过ksoap2传递复杂数据类型及CXF发布的webservice详细介绍
- ofbiz的webservice接口提供(4)-支持复杂数据类型方法
- (三)CXF之处理输入参数与输出类型为复杂类型的webService服务