CXF作为Web Service的实现框架,在消息传递过程中需要把参数或返回值当中某种数据类型的数据转化为XML格式的数据。在解析数据过程中又需要把XML格式的数据转化回原来的某种数据类型
CXF作为Web Service的实现框架,在消息传递过程中需要把参数或返回值当中某种数据类型的数据转化为XML格式的数据。在解析数据过程中又需要把XML格式的数据转化回原来的某种数据类型的数据。
但是CXF只支持String,基本数据类型,JavaBean类型,List集合,数组的转化,不支持Map及非JavaBean的类型的转换。
那么,当参数或返回值是Map类型,怎么办呢?
这时候适配器就配上用场了。我们的解决思路是:
- 假如服务方法的参数为Map类型,我们就让客户端传的参数为另一个可以处理的类型,如JavaBean,网络传输XML格式的数据,服务端解析成JavaBean之后,再通过适配器将JavaBean转换成Map类型参数。
- 假如服务方法的返回值为Map类型,我们就让适配器把Map转换成可以处理的类型,返回给客户端,如JavaBean。
代码示例
实现类
@WebService(endpointInterface = "com.tgb.ws.HelloWorld",serviceName = "HelloWorldWS")
public class HelloWorldWS implements HelloWorld {
public Map<String, Cat> getAllCats() {
UserService us=new UserServiceImpl();
return us.getAllCats();
}
}
接口
@WebService
public interface HelloWorld {
@XmlJavaTypeAdapter(FkXMLAdapter.class) Map<String,Cat> getAllCats();
}
这里,我们用到了@XmlJavaTypeAdapter注解,FkXMLAdapter是我们自定义的继承了XMLAdapter的适配器类。
适配器
public class FkXMLAdapter extends XmlAdapter<StringCat,Map<String,Cat>> {
@Override
public Map<String, Cat> unmarshal(StringCat v) throws Exception {
List<Entry> entries=v.getEntries();
Map<String,Cat> map=new HashMap<String,Cat>();
if(entries!=null){
for(Entry e:entries){
map.put(e.getKey(),e.getValue());
}
}
return map;
}
@Override
public StringCat marshal(Map<String, Cat> v) throws Exception {
System.out.println("--------------------Mar");
StringCat sc=new StringCat();
List<Entry> entries=new ArrayList<>();
sc.setEntries(entries);
if(v!=null){
for(String key:v.keySet()){
Entry entry=new Entry(key,v.get(key));
entries.add(entry);
}
}
return sc;
}
}
这里有两个方法,一个是marshal,一个是unmarshal。 marshal:是把CXF不支持的对象转化为支持的对象。 unmarshal:是把支持的对象转化为不支持的对象。 所谓支持的对象就是可以转化为XML的。