• cxf处理java bean及List、Map类型


          项目中经常是处理复合类型比如集合List、Map,下面就cxf处理复合类型进行讲解。

    具体例子如下:

       这里实例是客户端传一个JavaBean,服务器端返回集合类型;

     一、  接口返回List处理:

        在原来的项目实例(cxf开发webService服务端口)基础上,我们先创建一个实体类User:

     1 /**
     2  * 
     3  */
     4 package com.hik.entity;
     5 
     6 /**
     7  * @ClassName: User
     8  * @Description: 用户实体类
     9  * @author jed
    10  * @date 2017年7月30日下午2:44:41
    11  *
    12  */
    13 public class User {
    14 
    15     private Integer id; // 编号
    16     private String userName; //用户名
    17     private String password; //密码
    18     
    19     public Integer getId() {
    20         return id;
    21     }
    22     public void setId(Integer id) {
    23         this.id = id;
    24     }
    25     public String getUserName() {
    26         return userName;
    27     }
    28     public void setUserName(String userName) {
    29         this.userName = userName;
    30     }
    31     public String getPassword() {
    32         return password;
    33     }
    34     public void setPassword(String password) {
    35         this.password = password;
    36     }
    37     
    38     
    39 }
    View Code

    再创建一个Role实体类:

     1 /**
     2  * 
     3  */
     4 package com.hik.entity;
     5 
     6 /**
     7  * @ClassName: Role
     8  * @Description: TODO
     9  * @author jed
    10  * @date 2017年7月30日下午2:46:45
    11  *
    12  */
    13 public class Role {
    14 
    15     private Integer id; //编号
    16     private String roleName; //角色名称
    17     
    18     public Role() {
    19         super();
    20     }
    21 
    22     public Role(Integer id, String roleName) {
    23         super();
    24         this.id = id;
    25         this.roleName = roleName;
    26     }
    27     
    28     public Integer getId() {
    29         return id;
    30     }
    31     public void setId(Integer id) {
    32         this.id = id;
    33     }
    34     public String getRoleName() {
    35         return roleName;
    36     }
    37     public void setRoleName(String roleName) {
    38         this.roleName = roleName;
    39     }
    40     
    41     
    42 }
    View Code

    然后HelloWorld再加一个接口方法getRoleByUser,通过用户查找角色:

     1 /**
     2  * 
     3  */
     4 package com.hik.webservice;
     5 
     6 import java.util.List;
     7 
     8 import javax.jws.WebService;
     9 
    10 import com.hik.entity.Role;
    11 import com.hik.entity.User;
    12 
    13 /**
    14  * @ClassName: HelloWorld
    15  * @Description: TODO
    16  * @author jed
    17  * @date 2017年7月30日上午10:20:35
    18  *
    19  */
    20 @WebService
    21 public interface HelloWorld {
    22 
    23     public String say(String str);
    24     
    25     public List<Role> getRoleByUser(User user);
    26 }
    View Code

    然后HelloWorld接口实现类 HelloWorldImpl写下新增的方法的具体实现,我们这里写死,模拟下即可:

     1 /**
     2  * 
     3  */
     4 package com.hik.webservice.impl;
     5 
     6 import java.util.ArrayList;
     7 import java.util.List;
     8 
     9 import javax.jws.WebService;
    10 
    11 import com.hik.entity.Role;
    12 import com.hik.entity.User;
    13 import com.hik.webservice.HelloWorld;
    14 
    15 /**
    16  * @ClassName: HelloWorldImpl
    17  * @Description: TODO
    18  * @author jed
    19  * @date 2017年7月30日上午10:24:46
    20  *
    21  */
    22 @WebService
    23 public class HelloWorldImpl implements HelloWorld{
    24 
    25     public String say(String str) {
    26         return "hello "+str;
    27     }
    28 
    29     public List<Role> getRoleByUser(User user) {
    30         List<Role> roleList = new ArrayList<Role>();
    31         if(user!=null){
    32             if(user.getUserName().equals("jack") && user.getPassword().equals("123456")){
    33                 roleList.add(new Role(1, "技术总监"));
    34                 roleList.add(new Role(2, "产品经理"));
    35             }else if(user.getUserName().equals("lili") && user.getPassword().equals("123456")){
    36                 roleList.add(new Role(3, "程序员"));
    37             }
    38             return roleList;
    39         }else{
    40             return null;
    41         }
    42                 
    43     }
    44 
    45 }
    View Code

    服务端其他地方不用动;再重新发布下webService接口。

    下面我们来处理下客户端,和前面讲的一样。我们用wsdl2java工具重新生成代码(参考cxf开发webService客户端及调用服务端的理解 )

    我们改下Client类:

     1 /**
     2  * 
     3  */
     4 package com.hik.webservice;
     5 
     6 import java.util.List;
     7 
     8 /**
     9  * @ClassName: Client
    10  * @Description: TODO
    11  * @author jed
    12  * @date 2017年7月30日下午1:58:36
    13  *
    14  */
    15 public class Client {
    16 
    17     public static void main(String[] args) {
    18         HelloWorldService service = new HelloWorldService();
    19         HelloWorld helloWorld = service.getHelloWorldPort(); //代理
    20         //System.out.println(helloWorld.say("你好!"));
    21         User user = new User();
    22         user.setUserName("lili");
    23         user.setPassword("123456"); 
    24         List<Role> roleList = helloWorld.getRoleByUser(user);
    25         for(Role role : roleList){
    26             System.out.println(role.getId()+" , "+role.getRoleName());
    27         }
    28     }
    29 }
    View Code

    运行截图:

    二、接口返回Map处理

          map类型比较特殊,由其数据结构而决定。XmlAdapter类源码也有说明:

     因此,需要写一个适配器来做转换,使用注解annotation注解 。该适配器类需实现抽象类XmlAdapter的两个转换方法。

     代码例子如下:

      如增加接口:获取所有用用户以及对应的每个用户所有角色信息;

    服务器端:

    HelloWorld接口加方法:

     1 /**
     2      * 
     3      * @MethodName: getRoles
     4      * @Description: 获取所有用户及对应角色
     5      * @author jed
     6      * @date 2017年8月4日下午10:36:59
     7      * @param @return    
     8      * @return Map<String,List<Role>>    返回类型
     9      * @return
    10      *
    11      */
    12     @XmlJavaTypeAdapter(MapAdapter.class)
    13     public Map<String, List<Role>> getRoles();
    View Code

     HelloWorldImpl实现类加方法实现:

     1 public Map<String, List<Role>> getRoles() {
     2         Map<String, List<Role>> map = new HashMap<String, List<Role>>();
     3         List<Role> roleList1 = new ArrayList<Role>();
     4         roleList1.add(new Role(1, "技术总监"));
     5         roleList1.add(new Role(2, "产品经理"));
     6         map.put("admin", roleList1);
     7         List<Role> roleList2 = new ArrayList<Role>();
     8         roleList2.add(new Role(3, "程序员"));
     9         map.put("jack", roleList2);
    10         return map;
    11     }
    View Code

    然后我们启动Server类:发现报错:

     报错显示不支持该类型,解决方案,可以使用适配器,把cxf不能接受的类型通过适配器,转能接受的类型。

          我们使用@XmlJavaTypeAdapter注解,加在接口定义上,完整接口代码如下:

     1 /**
     2  * 
     3  */
     4 package com.hik.webservice;
     5 
     6 import java.util.List;
     7 import java.util.Map;
     8 
     9 import javax.jws.WebService;
    10 import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
    11 
    12 import com.hik.adapter.MapAdapter;
    13 import com.hik.entity.Role;
    14 import com.hik.entity.User;
    15 
    16 /**
    17  * @ClassName: HelloWorld
    18  * @Description: TODO
    19  * @author jed
    20  * @date 2017年7月30日上午10:20:35
    21  *
    22  */
    23 @WebService
    24 public interface HelloWorld {
    25 
    26     public String say(String str);
    27     
    28     /**
    29      * 
    30      * @MethodName: getRoleByUser
    31      * @Description: 获取用户角色 
    32      * @author jed
    33      * @date 2017年8月4日下午10:37:30
    34      * @param @param user
    35      * @param @return    
    36      * @return List<Role>    返回类型
    37      * @param user
    38      * @return
    39      *
    40      */
    41     public List<Role> getRoleByUser(User user);
    42     
    43     /**
    44      * 
    45      * @MethodName: getRoles
    46      * @Description: 获取所有用户及对应角色
    47      * @author jed
    48      * @date 2017年8月4日下午10:36:59
    49      * @param @return    
    50      * @return Map<String,List<Role>>    返回类型
    51      * @return
    52      *
    53      */
    54     @XmlJavaTypeAdapter(MapAdapter.class)
    55     public Map<String, List<Role>> getRoles();
    56 }
    View Code

    这里参数需要一个实现了XmlAdapter类的适配器类;

    这里的话XmlAdapter要加两个参数,XmlAdapter<ValueType,BoundType> 

    ValueType是cxf能接收的类型,这里我用了数组;

    BoundType是cxf不能接受的类型,也就是我例子里的需求的Map类型;

     1 /**
     2  * 
     3  */
     4 package com.hik.adapter;
     5 
     6 import java.util.HashMap;
     7 import java.util.List;
     8 import java.util.Map;
     9 
    10 import javax.xml.bind.annotation.adapters.XmlAdapter;
    11 
    12 import com.hik.entity.Role;
    13 
    14 /**
    15  * @ClassName: MapAdapter
    16  * @Description: Map适配器
    17  * @author jed
    18  * @date 2017年8月4日下午10:56:41
    19  *
    20  */
    21 public class MapAdapter extends XmlAdapter<MyRole[], Map<String, List<Role>>>{
    22 
    23     /**
    24      * 适配转换  MyRole[] -> Map<String, List<Role>>
    25      */
    26     @Override
    27     public Map<String, List<Role>> unmarshal(MyRole[] v) throws Exception {
    28         Map<String, List<Role>> map = new HashMap<String, List<Role>>();
    29         for(int i=0;i<v.length;i++){
    30             MyRole r = v[i];
    31             map.put(r.getKey(), r.getValue());
    32         }
    33         return map;
    34     }
    35 
    36      /**
    37      * 适配转换  Map<String, List<Role>> -> MyRole[]
    38      */
    39     @Override
    40     public MyRole[] marshal(Map<String, List<Role>> v) throws Exception {
    41         MyRole[] roles = new MyRole[v.size()];
    42         int i=0;
    43         for(String key : v.keySet()){
    44             roles[i] = new MyRole();
    45             roles[i].setKey(key);
    46             roles[i].setValue(v.get(key));
    47             i++;
    48         }
    49         
    50         return roles;
    51     }
    52 
    53 }
    View Code

    还有一个MyRole自定义类型,key:value。我们搞成两个属性,具体实现如下:

     1 /**
     2  * 
     3  */
     4 package com.hik.adapter;
     5 
     6 import java.util.List;
     7 
     8 import com.hik.entity.Role;
     9 
    10 /**
    11  * @ClassName: MyRole
    12  * @Description: 自定义实体 cxf能接受
    13  * @author jed
    14  * @date 2017年8月4日下午11:01:23
    15  *
    16  */
    17 public class MyRole {
    18 
    19     private String key;
    20     private List<Role> value;
    21     
    22     public String getKey() {
    23         return key;
    24     }
    25     public void setKey(String key) {
    26         this.key = key;
    27     }
    28     public List<Role> getValue() {
    29         return value;
    30     }
    31     public void setValue(List<Role> value) {
    32         this.value = value;
    33     }
    34     
    35     
    36 }
    View Code

    OK  好了。我们运行Server类,发布webservice接口:

    发布成功。然后就到了webservice客户端,我们用wsdl2java工具生成下最新代码

    我们修改下Client类:

     1 /**
     2  * 
     3  */
     4 package com.hik.webservice;
     5 
     6 import java.util.List;
     7 
     8 /**
     9  * @ClassName: Client
    10  * @Description: TODO
    11  * @author jed
    12  * @date 2017年7月30日下午1:58:36
    13  *
    14  */
    15 public class Client {
    16 
    17     public static void main(String[] args) {
    18         HelloWorldService service = new HelloWorldService();
    19         HelloWorld helloWorld = service.getHelloWorldPort(); //代理
    20         //System.out.println(helloWorld.say("你好!"));
    21         /*User user = new User();
    22         user.setUserName("lili");
    23         user.setPassword("123456"); 
    24         List<Role> roleList = helloWorld.getRoleByUser(user);
    25         for(Role role : roleList){
    26             System.out.println(role.getId()+" , "+role.getRoleName());
    27         }*/
    28         MyRoleArray array = helloWorld.getRoles();
    29         List<MyRole> roleList = array.item;
    30         for(int i=0;i<roleList.size();i++){
    31             MyRole mr = roleList.get(i);
    32             System.out.println(mr.key+":");
    33             for(Role r: mr.getValue()){
    34                 System.out.println(r.getId()+","+r.getRoleName()+" ");
    35             }
    36             System.out.println();
    37         }
    38     }
    39 }
    View Code

    运行结果:

        总结: webService处理过程如下:

    1、webservice服务器端开发webservice接口,然后发布webservice;

    2、通过一个Url调用webservice接口,发布的url是 http://192.168.0.102/helloWorld,则我们请求的url就是 http://192.168.0.102/helloWorld?wsdl  

    3、请求成功,返回一大串xml标记。这一大串xml即使wsdl。   wsdl (Web Services Description Language) 也就是Web Service描述语言,描述服务器端定义的webservice接口的相关信息。

    4、wsdl描述可看到发布的方法。如:wsdl:types就是定义了一些变量,wsdl:message相当于定义方法,wsdl:portType相当与调用与返回。

    5、客户端通过这个url请求,获得wsdl规范的xml文档片段信息,需用到SOAP(Simple Object Access Protocol)即简单对象访问协议,我们通过这个协议,来实现客户端,服务器端消息交互,SOAP使用XML消息调用远程方法;

         当然交互的媒介就是xml,具体交互内容根据wsdl文档描述来。

  • 相关阅读:
    数据库多表查询,左连接(入门)
    让弹出层始终显示在屏幕正中间
    jq中的ajax合集总结
    ajax之$.getScript()
    Jquery遮罩ShowLoading组件
    jquery中prop()方法和attr()方法的区别
    Bootstrap 响应式实用工具
    VS使用技巧
    ubuntu下postgreSQL安装配置
    基础设施即代码(Infrastructure as Code)
  • 原文地址:https://www.cnblogs.com/jedjia/p/cxf_map_list.html
Copyright © 2020-2023  润新知