【WebService】CXF处理javaBean等复合类型以及Map等复杂类型的数
在实际中除了传入一些基本的参数以外,还需要传入一些类似于javaBean等复合类型,或者Map等复杂类型的数据,这一篇博文主要来写两个demo,模拟一下CXF处理这类数据的过程。 1. CXF处理javaBean等复合类型的数据客户端提交一个数据过去,要检查权限,比如是管理员的话,就拥有多个权限,普通用户可能就一个权限之类的。这样的话需要一个用户的bean和权限的bean,然后数据库的数据我用List来模拟一下,demo如下: public class User {
private Integer id;
private String name;
private String password;
//……
}
public class Role {
private Integer id;
private String roleName; //角色名称
//……
}
ws的程序如下: //接口
@WebService
public interface MyWebService {
public String sayHello(String str);
public List<Role> getRoleByUser(User user);
}
//实现类
@WebService
public class MyWebServiceImpl implements MyWebService{
public String sayHello(String str) {
return "Hello" + str;
}
public List<Role> getRoleByUser(User user) {
List<Role> roleList = new ArrayList<Role>();
if(user != null) {
if(user.getName().equals("admin") && user.getPassword().equals("123")) {
roleList.add(new Role(1,"技术总监"));
roleList.add(new Role(2,"架构师"));
} else if(user.getName().equals("eson15") && user.getPassword().equals("123")) {
roleList.add(new Role(3,"java菜鸟"));
}
return roleList;
} else {
return null;
}
}
}
主要来看getRoleByUser这个方法,当然了,也可以使用注解去配置一下要生成的wsdl,这里就不配置了,使用默认的即可,方法中自定义了一个List用来存储角色信息的,模拟的是先判断用户的身份,然后根据不同的身份赋予不同的角色。 public class _Main {
public static void main(String[] args) {
MyWebServiceService service = new MyWebServiceService();
MyWebService port = service.getMyWebServicePort();
User user = new User();
user.setName("admin");
user.setPassword("123");
List<Role> roleList = port.getRoleByUser(user);
for(Role role : roleList) {
System.out.println(role.getId() + "," + role.getRoleName());
}
}
}
这里为了模拟,直接new一个admin用户,然后调用ws的getRoleByUser方法获取该用户的角色,打印到控制台,结果肯定是两个角色,如果是eson15,那就是一个java菜鸟的角色了。 2. CXF处理Map等复杂类型的数据CXF是无法直接操作Map类型的数据的,需要进行一些处理才行。我们先写一个获取所有角色信息的方法,先看一下会出啥问题。 //接口
@WebService
public interface MyWebService {
//这个注解等会有用,先注释掉
//@XmlJavaTypeAdapter(MapAdapter.class)
public Map<String,List<Role>> getRoles();
}
// 实现类
@WebService
public class MyWebServiceImpl implements MyWebService{
// 省去上面不相关代码
public Map<String,List<Role>> getRoles() {
Map<String,List<Role>> map = new HashMap<String,List<Role>>();
List<Role> roleList = new ArrayList<Role>();
roleList.add(new Role(1,"技术总监"));
roleList.add(new Role(2,"架构师"));
map.put("admin",roleList);
List<Role> roleList2 = new ArrayList<Role>();
roleList2.add(new Role(1,"java菜鸟"));
map.put("eson15",roleList2);
return map;
}
}
这里还是使用静态数据模拟一下,Map中存储了两个用户,admin用户有两个角色,eson15用户就一个角色,当这个ws发布后,客户端可以调用getRoles方法获取这些角色,但是我们会发现,这个ws是无法发布的,控制台会报错。因为CXF要处理Map类型的数据,还需要一些转换工作。 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>>();
for(int i = 0; i < v.length; i++) {
MyRole role = v[i];
map.put(role.getKey(),role.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()) {
List<Role> rolesList = v.get(key);
roles[i] = new MyRole();
roles[i].setKey(key);
roles[i].setValue(rolesList);
i++;
}
return roles;
}
}
MapAdapter需要继承XmlAdapter,这个XmlAdapter的泛型里两个参数指的是从什么转到什么?即那两个对象之间在转换,这里需要转Map对象,一般我们会用一个数组对象来和Map对象进行转换,所以我们自定义一个MyRole[]数组: public class MyRole {
private String key;
private List<Role> value;
//……
}
数组中保存了MyRole对象,而这个对象中的两个属性要符合Map的结构,所以我们就好转了。 public class _Main {
public static void main(String[] args) {
MyWebServiceService service = new MyWebServiceService();
MyWebService port = service.getMyWebServicePort();
// 省去不相关代码
List<MyRole> roles = port.getRoles().getItem();
for(MyRole myrole : roles) {
System.out.print("key:" + myrole.getKey() + ",");
System.out.print("role:");
for(Role role : myrole.getValue()) {
System.out.print(role.getRoleName() + " ");
}
System.out.println();
}
}
}
看下输出的结果:
所以CXF处理像Map等复杂类型的数据的时候,还需要先进行一些转换的处理,才能正常发布ws服务,不过也不算太麻烦。 —–乐于分享,共同进步! (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |