前面一些都是简单类型,cxf都支持。但是有些复杂类型,cxf是不支持,比如常用的Map类型
下面我们在前面的实例基础上在加一个方法,比如我们现在有个需求,获取所有用用户以及对应的每个用户所有角色信息
在HelloWorld接口上写一个Map接口
public Map<String,List<Role>> getRoles();
在HelloWorldImpl实现类上编写实现
public Map<String, List<Role>> getRoles() {
Map<String,List<Role>> map=new HashMap<String,List<Role>>();
List<Role> roleList1=new ArrayList<Role>();
roleList1.add(new Role(1,"技术总监"));
roleList1.add(new Role(2,"架构师"));
map.put("gcx", roleList1);
List<Role> roleList2=new ArrayList<Role>();
roleList2.add(new Role(3,"程序员"));
map.put("jack", roleList2);
return map;
}
运行服务报错:
解决办法
在HelloWorld接口的方法上加上注解
@XmlJavaTypeAdapter(MapAdapter.class)
public Map<String,List<Role>> getRoles();
然后创建一个类叫MapAdapter 继承 XmlAdapter
package com.gcx.Adapter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import com.gcx.entity.Role;
public class MapAdapter extends XmlAdapter<MyRole[], Map<String,List<Role>>> {
@Override
public Map<String, List<Role>> unmarshal(MyRole[] v) throws Exception {
Map<String,List<Role>> map=new HashMap<String,List<Role>>();
for(int i=0;i<v.length;i++){
MyRole role=v[i];
map.put(role.getKey(), role.getValue());
}
return map;
}
@Override
public MyRole[] marshal(Map<String, List<Role>> v) throws Exception {
MyRole[] roles=new MyRole[v.size()];
int i=0;
for(String key:v.keySet()){
roles[i]=new MyRole();
roles[i].setKey(key);
roles[i].setValue(v.get(key));
i++;
}
return roles;
}
}
这里的话XmlAdapter要加两个参数,XmlAdapter<ValueType,BoundType>
ValueType是cxf能接收的类型,这里我用了数组
BoundType是cxf不能接受的类型,也就是我例子里的需求的Map类型
还有一个MyRole自定义类型,key:value。我们搞成两个属性,具体实现如下
package com.gcx.Adapter;
import java.util.List;
import com.gcx.entity.Role;
/**
* cxf能够接受自定义实体
* @author gcx
*
*/
public class MyRole {
private String key;
private List<Role> value;
public MyRole() {
// TODO Auto-generated constructor stub
}
public MyRole(String key, List<Role> value) {
super();
this.key = key;
this.value = value;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public List<Role> getValue() {
return value;
}
public void setValue(List<Role> value) {
this.value = value;
}
@Override
public String toString() {
return "MyRole [key=" + key + ", value=" + value + "]";
}
}
OK 这样就行了。我们运行Server类,发布webservice接口
然后就到了webservice客户端,我们用wsdl2java工具生成下最新代码,具体过程前面讲过,这里不重复
我们修改下Client类
package com.gcx.service;
import java.util.List;
public class Client {
public static void main(String[] args) {
HelloWorldService service=new HelloWorldService();
HelloWorld helloWorld=service.getHelloWorldPort();
MyRoleArray roles = helloWorld.getRoles();
List<MyRole> item = roles.item;
for(int i=0;i<item.size();i++){
MyRole myRole = item.get(i);
System.out.print(myRole.key+":");
for(Role my:myRole.value){
System.out.print(my.getId()+","+my.getRoleName());
}
System.out.println("==");
}
}
}
运行结果如下:
OK,这样就实现了复杂类型的调用!!!