from:
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的接口
- @WebService??
- public?interface?HelloWorld?{??
- ??????
- ????@XmlJavaTypeAdapter((XmlMapAdapter.class))?Map<String,?String>?getSpace(String?deviceIp);??
- ??????
- }??
实现类保持不变:
- @Component("hello")??
- @WebService(endpointInterface?=?"demo.spring.service.HelloWorld")??
- public?class?HelloWorldImpl?implements?HelloWorld?{??
- ??
- ??
- ??
- ??
- ????public?Map<String,?String>?getSpace(String?deviceIp)?{??
- ????????//?TODO?Auto-generated?method?stub??
- ????????HashMap<String,?String>?test?=?new?HashMap<String,String>();??
- ????????test.put("test",??"10.5");??
- ????????test.put("ip",?deviceIp);??
- ??????????
- ????????System.out.println("deviceIp:?"?+?deviceIp);??
- ??????????
- ????????return?test;??
- ????}??
- }??
2.定义自行创建的XmlMapAdapter类型
- public?class?XmlMapAdapter?extends?XmlAdapter<MyStringMap,?Map<String,?String>>?{??
- ??
- ????@Override??
- ????public?Map<String,?String>?unmarshal(MyStringMap?v)?throws?Exception?{??
- ????????//?TODO?Auto-generated?method?stub??
- ??????????
- ????????Map<String,?String>?result?=?new?HashMap<String,?String>();??
- ??????????
- ????????for?(Entry?entry?:?v.getEntries())?{??
- ????????????result.put(entry.getKey(),?entry.getValue());??
- ????????}??
- ??????????
- ????????return?result;??
- ????}??
- ??
- ????@Override??
- ????public?MyStringMap?marshal(Map<String,?String>?v)?throws?Exception?{??
- ????????//?TODO?Auto-generated?method?stub??
- ????????MyStringMap?msm?=?new?MyStringMap();??
- ????????List<Entry>?eList?=?new?ArrayList<Entry>();??
- ????????for(String?key?:?v.keySet())?{??
- ??????????????
- ????????????Entry?entry?=?new?Entry();??
- ????????????entry.setKey(key);??
- ????????????entry.setValue(v.get(key));??
- ????????????eList.add(entry);??
- ????????}??
- ????????msm.setEntries(eList);??
- ????????return?msm;??
- ????}??
- ??
- ??????
- ??
- }??
通过继承
XmlAdapter<ValueType,BoundType>类型,便可已将CXF不能处理的类型进行转换。
jdkAPI中定义如下,valuType是能够处理的类型,boundType是不能处理的类型:
转化的实质是将不能处理的类型,如Map,将其值取出,赋予另一个实体类,这个类模拟Map,保存他的值,这样便是可以进行相互转化。为此,需要定义一个Map的模拟类,这样Map的key和value都保存在Entry类中(Entry自行定义,名字也可以随便,只要符合命名规范就行),所有的Entry保存在List中,这样一个Map集合就转化成了MyStringMap类,MyStringMap自然也可以转化为Map类:
- public?class?MyStringMap?{??
- ??????
- ????private?List<Entry>?entries;??
- ??
- ????/**??
- ?????*?@return?entries??
- ?????*/??
- ????public?List<Entry>?getEntries()?{??
- ????????return?entries;??
- ????}??
- ??
- ????/**??
- ?????*?@param?entries?the?entries?to?set??
- ?????*/??
- ????public?void?setEntries(List<Entry>?entries)?{??
- ????????this.entries?=?entries;??
- ????}??
- ??????
- ????public?static?class?Entry?{??
- ????????private?String?key;??
- ????????private?String?value;??
- ????????/**??
- ?????????*?@return?key??
- ?????????*/??
- ????????public?String?getKey()?{??
- ????????????return?key;??
- ????????}??
- ????????/**??
- ?????????*?@param?key?the?key?to?set??
- ?????????*/??
- ????????public?void?setKey(String?key)?{??
- ????????????this.key?=?key;??
- ????????}??
- ????????/**??
- ?????????*?@return?value??
- ?????????*/??
- ????????public?String?getValue()?{??
- ????????????return?value;??
- ????????}??
- ????????/**??
- ?????????*?@param?value?the?value?to?set??
- ?????????*/??
- ????????public?void?setValue(String?value)?{??
- ????????????this.value?=?value;??
- ????????}??
- ??????????
- ??????????
- ????}???
- ??????
- }??
- java.lang.Object
- javax.xml.bind.annotation.adapters.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.测试客户端:
- public?static?void?main(String?[]args)?{??
- ???????HelloWorldImplService?service?=?new?HelloWorldImplService();??
- ?????????
- ???????HelloWorld?hw?=?service.getHelloWorldImplPort();??
- ?????????
- ???????MyStringMap?msm?=?hw.getSpace("");??
- ?????????
- ???????List<Entry>?entries?=?msm.getEntries();??
- ?????????
- ???????for?(Entry?e?:?entries)?{??
- ???????????System.out.println("key:?"?+?e.getKey()?+?"?"?+?"value:?"?+?e.getValue());??
- ???????}??
- ???}??
结果如下:
- 2013-4-3?15:56:19?org.apache.cxf.service.factory.ReflectionServiceFactoryBean?buildServiceFromWSDL??
- 信息:?Creating?Service?{http://service.spring.demo/}HelloWorldImplService?from?WSDL:?http://192.168.1.133:8088/CXFUseCase/services/helloWorld?wsdl??
- key:?test?value:?10.5??
- key:?ip?value:?192.168.3.51??
至此,转化操作完成。