前面博主写的一些都是简单类型,cxf都支持。但是有些复杂类型,cxf是不支持,比如常用的Map类型;
下面我们在前面的实例基础上在加一个方法,比如我们现在有个需求,获取所有用用户以及对应的每个用户所有角色信息;
服务器端还是我们以前的项目:
在HelloWorld接口加方法:
package com.oyyp.webservice;
import java.util.List;
import java.util.Map;
import javax.jws.WebService;
import com.oyyp.entity.Role;
import com.oyyp.entity.User;
@WebService
public interface HelloWorld {
public String say(String str);
public List<Role> getRoleByUser(User user);
/**
* 获取所有用户以及对应的角色
* @return
*/
public Map<String, List<Role>> getAllRoles();
}
在HelloWorldImpl实现类加方法实现:
package com.oyyp.webservice.impl;
import com.oyyp.entity.Role;
import com.oyyp.entity.User;
import com.oyyp.webservice.HelloWorld;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.jws.WebService;
@WebService
public class HelloWorldImpl implements HelloWorld{
public String say(String str) {
// TODO Auto-generated method stub
return "Hello:"+str;
}
public List<Role> getRoleByUser(User user) {
List<Role> roleList=new ArrayList<Role>();
// 模拟 直接写死
if(user!=null){
if(user.getUserName().equals("tom") && user.getPassWord().equals("123456")){
roleList.add(new Role(1,"技术总监"));
roleList.add(new Role(2,"架构师"));
}else if(user.getUserName().equals("jack") && user.getPassWord().equals("123456")){
roleList.add(new Role(3,"程序员"));
}
return roleList;
}else{
return null;
}
}
public Map<String, List<Role>> getAllRoles() {
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("tom", roleList1);
List<Role> roleList2=new ArrayList<Role>();
roleList2.add(new Role(3,"程序员"));
map.put("jack", roleList2);
return map;
}
}
然后我们启动Server类:发现报错:这个报错信息是,不支持该类型;
解决这种问题有好几种方案,我只写一种,也是我们开发常用的:使用适配器。把cxf不能接受的类型通过适配器,转能接受的类型。
我们使用@XmlJavaTypeAdapter注解,加在接口定义上,代码如下:
package com.oyyp.webservice;
import java.util.List;
import java.util.Map;
import javax.jws.WebService;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import com.oyyp.entity.Role;
import com.oyyp.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>> getAllRoles();
}
这里参数需要一个实现了XmlAdapter类的适配器类;
package com.oyyp.adapter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import com.oyyp.entity.MyRole;
import com.oyyp.entity.Role;
/**
* Map适配器
* @author Administrator
*
*
* XmlAdapter<ValueType, BoundType> 从什么类型到什么类型
*
*/
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
package com.oyyp.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;
}
}
这样就行了。我们运行Server类,发布webservice接口:
然后就到了webservice客户端,我们用wsdl2java工具生成下最新代码,具体过程前面的博客,这里不重复讲:
我们修改下Client类:
package com.oyyp.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("Web Service 你大爷的"));
// User user=new User();
// user.setUserName("jack");
// user.setPassWord("123456");
// List<Role> roles=helloWorld.getRoleByUser(user);
// for (Role role : roles) {
// System.out.println(role.getId()+"-"+role.getRoleName());
// }
MyRoleArray array=helloWorld.getAllRoles();
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();
}
}
}
运行如下:
这样就实现了复杂类型的调用。