微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

webservice学习之处理Map等CXF无法自动转化的类型

转自:http://blog.csdn.net/wlsyn/article/details/8756068


CXF形参、返回值
      1. 当形参和返回值的类型是String、基本数据类型是,CXF肯定可以轻松处理
       2.当形参和返回值的类型是javabean式的复合类(就是普通的POJO实体类)、List集合、数组等复杂类型时, CXF也可以很好处理。
       3.还有一些像Map、非javabean式的复合类,CXF是处理不了的

如果遇到系统无法自动处理的类型,就需要程序员自行处理,方法是提供一个转化器,该转化器负责把CXF不能处理的类型,转化为CXF能够处理的类型,具体过程如下:
(1) 使用注解 @XmlJavaTypeAdapter(java自身的注解,可在jdkapi文档中查到)修饰CXF无法自动处理的类型,使用该Annotation时,通过value属性指定一个转换器(自己定义)。
@XmlJavaTypeAdapter (value="MyXmlAdapter.class") 

(2) 实现自己定义的转化器,实现转化器时,需要开发一个CXF能够处理的类型。

1. 注解@XmlJavaTypeAdapter标识返回值为Map的接口

[html]  view plain copy
  1. @WebService  
  2. public interface HelloWorld {  
  3.       
  4.     @XmlJavaTypeAdapter((XmlMapAdapter.class)) Map<String, String> getSpace(String deviceIp);  
  5. }  
copy
      
copy
      
实现类保持不变:
[html]  view plain copy
    @Component("hello")  
  1. @WebService(endpointInterface = "demo.spring.service.HelloWorld")  
  2. public class HelloWorldImpl implements HelloWorld {  
  3.   
  4.   
  5.     public Map> getSpace(String deviceIp) {  
  6.         // Todo Auto-generated method stub  
  7.         HashMap> test = new HashMap>();  
  8.         test.put("test",  "10.5");  
  9.         test.put("ip", deviceIp);  
  10.           
  11.         System.out.println("deviceIp: " + deviceIp);  
  12.         return test;  
  13.     }  
  14. }  


2.定义自行创建的XmlMapAdapter类型
copy
    public class XmlMapAdapter extends XmlAdapterMyStringMap, Map>> {  
  1.   
  2.     @Override  
  3. > unmarshal(MyStringMap v) throws Exception {  
  4.         // Todo Auto-generated method stub  
  5.           
  6.         Map> result = new HashMap>();  
  7.         for (Entry entry : v.getEntries()) {  
  8.             result.put(entry.getKey(), entry.getValue());  
  9.         }  
  10.         return result;  
  11.     }  
  12.   
  13.     @Override  
  14.     public MyStringMap marshal(Map> v) throws Exception {  
  15.         // Todo Auto-generated method stub  
  16.         MyStringMap msm = new MyStringMap();  
  17.         ListEntry> eList = new ArrayList>();  
  18.         for(String key : v.keySet()) {  
  19.               
  20.             Entry entry = new Entry();  
  21.             entry.setKey(key);  
  22.             entry.setValue(v.get(key));  
  23.             eList.add(entry);  
  24.         msm.setEntries(eList);  
  25.         return msm;  
  26.       
  27. }  
通过继承 XmlAdapter<ValueType,BoundType>类型,便可已将CXF不能处理的类型进行转换。
jdkAPI中定义如下,valuType是能够处理的类型,boundType是不能处理的类型:
转化的实质是将不能处理的类型,如Map,将其值取出,赋予另一个实体类,这个类模拟Map,保存他的值,这样便是可以进行相互转化。为此,需要定义一个Map的模拟类,这样Map的key和value都保存在Entry类中(Entry自行定义,名字也可以随便,只要符合命名规范就行),所有的Entry保存在List中,这样一个Map集合就转化成了MyStringMap类,MyStringMap自然也可以转化为Map类:
copy
    public class MyStringMap {  
  1.     private List> entries;  
  2.     /**  
  3.      * @return entries  
  4.      */  
  5.     public List> getEntries() {  
  6.         return entries;  
  7.     /**  
  8.      * @param entries the entries to set  
  9.      */  
  10.     public void setEntries(List> entries) {  
  11.         this.entries = entries;  
  12.     }  
  13.     public static class Entry {  
  14.         private String key;  
  15.         private String value;  
  16.         /**  
  17.          * @return key  
  18.          */  
  19.         public String getKey() {  
  20.             return key;  
  21.          * @param key the key to set  
  22.         public void setKey(String key) {  
  23.             this.key = key;  
  24.          * @return value  
  25.         public String getValue() {  
  26.             return value;  
  27.          * @param value the value to set  
  28.         public void setValue(String value) {  
  29.             this.value = value;  
  30.           
  31.     }   
  32. }  


avax.xml.bind.annotation.adapters

Class XmlAdapter<ValueType,BoundType>

  • Type Parameters:
    BoundType - The type that JAXB doesn't kNow how to handle. An adapter is written to allow this type to be used as an in-memory representation through the  ValueType.
    ValueType - The type that JAXB kNows how to handle out of the Box.

3.部署项目到tomcat中,启动,如能访问到WSDL文件,WSDL发布成功。

4.使用命令生成客户端,具体方法博文

5.测试客户端:
copy
    public static void main(String []args) {  
  1.        HelloWorldImplService service = new HelloWorldImplService();  
  2.          
  3.        HelloWorld hw = service.getHelloWorldImplPort();  
  4.        MyStringMap msm = hw.getSpace("");  
  5.        List> entries = msm.getEntries();  
  6.        for (Entry e : entries) {  
  7.            System.out.println("key: " + e.getKey() + " " + "value: " + e.getValue());  
  8.        }  
  9.    }  

结果如下:
copy
    2013-4-3 15:56:19 org.apache.cxf.service.factory.ReflectionServicefactorybean buildServiceFromWSDL  
  1. 信息: Creating Service {http://service.spring.demo/}HelloWorldImplService from WSDL: http://192.168.1.133:8088/CXFUseCase/services/helloWorld?wsdl  
  2. key: test value: 10.5  
  3. key: ip value: 192.168.3.51  
至此,转化操作完成。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐