转在CXF中用JAXB数据绑定支持Map类型
?一些java类型不能自然映射成xml,例如,HashMap 或其他非 JavaBean 类,这个时候可以覆盖XmlAdapter来自定义转换方法。
XMlAdapter讲解:
javax.xml.bind.annotation.adapters
类 XmlAdapter<ValueType,BoundType>类型参数: BoundType - JAXB 不知道如何处理的一些类型。编写一个适配器,以便允许通过 ValueType 将此类型用作内存表示形式。 ValueType - JAXB 无需其他操作便知道如何处理的类型。
?
引入
在CXF所些的服务端程序,被客户端程序调用时,SOAP中不支持Map(客户端传递Map参数或服务端返回Map数据),否则会如下错误:Marshalling Error: java.util.Map is not known to this context。
原因
CXF中不支持Map
解决方案
通过适配器将数组转换成HashMap的方式支持。
代码实现
1、? 定义Map转换器(code)
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
?
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlType;
?
/**
?* @author?wcp
?* @version 创建时间:2011-12-4 下午11:21:49
?* @DO????? Map转换器 ???????
?*/
@XmlType(name = "MapConvertor")??
@XmlAccessorType(XmlAccessType.FIELD)?
public class MapConvertor
{
??? private List<MapEntry> entries = new ArrayList<MapEntry>();
?
??? public void addEntry(MapEntry entry)
??? {
??????? entries.add(entry);
??? }
?
??? public static class MapEntry
??? {
??????? public MapEntry()
??????? {
??????????? super();
??????? }
?
??????? public MapEntry(Map.Entry<Object, Object> entry)
??????? {
??????????? super();
??????????? this.key = entry.getKey();
??????????? this.value = entry.getValue();
??????? }
?
??????? public MapEntry(Object key, Object value)
??????? {
??????????? super();
??????????? this.key = key;
??????????? this.value = value;
??????? }
?
??????? private String key;
??????? private Object value;
?
??????? public String getKey()
??????? {
??????????? return key;
??????? }
?
??????? public void setKey(String key)
??????? {
??????????? this.key = key;
??????? }
?
??????? public Object getValue()
??????? {
??????????? return value;
??????? }
?
??????? public void setValue(Object value)
??????? {
??????????? this.value = value;
??????? }
??? }
?
??? public List<MapEntry> getEntries()
??? {
??????? return entries;
??? }
}
?
?
2、? 定义Map适配器(code)
import java.util.HashMap;
import java.util.Map;
?
import javax.xml.bind.annotation.adapters.XmlAdapter;
?
/**
?* @author?wcp
?* @version 创建时间:2011-12-4 下午11:25:11
?* @DO?????? Map适配器???????
?*/
?
public class MapAdapter extends XmlAdapter<MapConvertor, Map<Object, Object>>
{
?
???@Override
?public MapConvertor marshal(Map<Object, Object> map) throws Exception {
??MapConvertor convertor = new MapConvertor();
??for(Map.Entry<Object, Object> entry:map.entrySet()){
???MapConvertor.MapEntry e = new MapConvertor.MapEntry(entry);
???convertor.addEntry(e);
??}
??return convertor;
?}
?@Override
?public Map<Object, Object> unmarshal(MapConvertor map) throws Exception {
??Map<Object, Object> result = new HashMap<Object,Object>();
??for(MapConvertor.MapEntry e :map.getEntries()){
???result.put(e.getKey(), e.getValue());
??}
??return result;
?}
}
3、? 在CXF服务端的接口程序中进行如下定义
??? @WebMethod?
??? @XmlJavaTypeAdapter(MapAdapter.class)??
??? Map<String, String> getMap();
进行以上3个步骤,就可以实现CXF中对Map的支持。