前面讲的一些都是简单类型,cxf都支持。可是有些复杂类型,cxf是不支持,好比经常使用的Map类型;java
下面咱们在前面的实例基础上在加一个方法,好比咱们如今有个需求,获取全部用用户以及对应的每一个用户全部角色信息;程序员
服务器端:web
HelloWorld接口加方法:数组
/** * 获取全部用户以及对应的角色 * @return */ public Map<String,List<Role>> getRoles();
HelloWorldImpl实现类加方法实现:服务器
public Map<String, List<Role>> getRoles() { // TODO Auto-generated method stub 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("wishwzp", roleList1); List<Role> roleList2=new ArrayList<Role>(); roleList2.add(new Role(1,"程序员")); map.put("jack", roleList2); return map; }
而后咱们启动Server类:发现报错:架构
这个报错信息说,不支持该类型;eclipse
这里咱们有好几种解决方案,这里咱们用最经常使用的一种,使用适配器,把cxf不能接受的类型经过适配器,转能接受的类型。ide
咱们使用@XmlJavaTypeAdapter注解,加在接口定义上,完整接口代码以下:工具
package com.wishwzp.webservice; import java.util.List; import java.util.Map; import javax.jws.WebService; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import com.wishwzp.adapter.MapAdapter; import com.wishwzp.entity.Role; import com.wishwzp.entity.User; @WebService public interface HelloWorld { public String say(String str); public List<Role> getRoleByUser(User user); /** * 获取全部用户以及对应的角色 * @return */ @XmlJavaTypeAdapter(MapAdapter.class) public Map<String,List<Role>> getRoles(); }
这里参数须要一个实现了XmlAdapter类的适配器类;测试
package com.wishwzp.adapter; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.xml.bind.annotation.adapters.XmlAdapter; import com.wishwzp.entity.MyRole; import com.wishwzp.entity.Role; /** * Map适配器 * @author Administrator * */ public class MapAdapter extends XmlAdapter<MyRole[], Map<String,List<Role>>>{ /** * 适配转换 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 r=v[i]; map.put(r.getKey(), r.getValue()); } return map; } /** * 适配转换 Map<String, List<Role>> -> MyRole[] */ @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.wishwzp.entity; import java.util.List; /** * 自定义实体 cxf能接受 * @author Administrator * */ public class MyRole { private String key; private List<Role> 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; } }
OK 这样就好了。咱们运行Server类,发布webservice接口:
而后就到了webservice客户端,咱们用wsdl2java工具生成下最新代码,具体过程前面讲过,这里不重复讲:
个人地址是:D:\eclipse_workspace\WS_Client\src\main\java 大家的可能和我不同:
而后咱们进入dos,进入上面的本地硬盘地址,而后执行命令:wsdl2java http://192.168.0.110/helloWorld?wsdl
生成代码以下:
咱们修改下Client类:
package com.wishwzp.webservice; import java.util.List; public class Client { public static void main(String[] args) { HelloWorldService service=new HelloWorldService(); HelloWorld helloWorld=service.getHelloWorldPort(); //System.out.println(helloWorld.say("wishwzp测试")); // User user=new User(); // user.setUserName("jack"); // user.setPassword("123456"); // List<Role> roleList=helloWorld.getRoleByUser(user); // for(Role role:roleList){ // System.out.println(role.getId()+","+role.getRoleName()); // } MyRoleArray array=helloWorld.getRoles(); List<MyRole> roleList=array.item; for(int i=0;i<roleList.size();i++){ MyRole my=roleList.get(i); System.out.print(my.key+":"); for(Role r:my.value){ System.out.print(r.getId()+","+r.getRoleName()+" "); } System.out.println(); } } }
运行下: