设为首页 收藏本站
查看: 337|回复: 0

[经验分享] Apache CXF实战之三 Map类型绑定

[复制链接]

尚未签到

发表于 2017-1-7 07:27:55 | 显示全部楼层 |阅读模式
  在CXF中,如果Web Service返回类型是Map的时候,比如方法签名如下
[java] view plaincopyprint?



  • @WebMethod  
  • @WebResult Map<String, User> getUserMap();  

  此时如果运行程序会得到类似下面的异常
[java] view plaincopyprint?



  • ...  
  • Caused by: com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 2 counts of IllegalAnnotationExceptions  
  • java.util.Map is an interface, and JAXB can't handle interfaces.  
  •     this problem is related to the following location:  
  •         at java.util.Map  
  •         at private java.util.Map com.googlecode.garbagecan.cxfstudy.type.sample2.jaxws_asm.GetUserMapResponse._return  
  •         at com.googlecode.garbagecan.cxfstudy.type.sample2.jaxws_asm.GetUserMapResponse  
  • java.util.Map does not have a no-arg default constructor.  
  •     this problem is related to the following location:  
  •         at java.util.Map  
  •         at private java.util.Map com.googlecode.garbagecan.cxfstudy.type.sample2.jaxws_asm.GetUserMapResponse._return  
  •         at com.googlecode.garbagecan.cxfstudy.type.sample2.jaxws_asm.GetUserMapResponse  
  •     at com.sun.xml.bind.v2.runtime.IllegalAnnotationsException$Builder.check(IllegalAnnotationsException.java:102)  
  •     at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:472)  
  •     at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:302)  
  •     at com.sun.xml.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1136)  
  •     at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:154)  
  •     at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:121)  
  •     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)  
  •     at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)  
  •     at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)  
  •     at java.lang.reflect.Method.invoke(Unknown Source)  
  •     at javax.xml.bind.ContextFinder.newInstance(Unknown Source)  
  •     at javax.xml.bind.ContextFinder.newInstance(Unknown Source)  
  •     at javax.xml.bind.ContextFinder.find(Unknown Source)  
  •     at javax.xml.bind.JAXBContext.newInstance(Unknown Source)  
  •     at org.apache.cxf.jaxb.JAXBDataBinding.createContext(JAXBDataBinding.java:560)  
  •     at org.apache.cxf.jaxb.JAXBDataBinding.createJAXBContextAndSchemas(JAXBDataBinding.java:500)  
  •     at org.apache.cxf.jaxb.JAXBDataBinding.initialize(JAXBDataBinding.java:320)  
  •     ... 25 more  
  • ...  

  如果把方法签名改为如下时
[java] view plaincopyprint?



  • @WebMethod  
  • @WebResult HashMap<String, User> getUserMap();  

  运行程序会发现返回的结果总是一个空的HashMap。
  对于以上问题,此时需要对Map类型做一下数据绑定或者说转换,看下面详细例子
  1. 首先是一个实体类
[java] view plaincopyprint?



  • package com.googlecode.garbagecan.cxfstudy.type.sample2;  
  •   
  • public class User {  
  •     private String id;  
  •     private String name;  
  •     private String password;  
  •     public String getId() {  
  •         return id;  
  •     }  
  •     public void setId(String id) {  
  •         this.id = id;  
  •     }  
  •     public String getName() {  
  •         return name;  
  •     }  
  •     public void setName(String name) {  
  •         this.name = name;  
  •     }  
  •     public String getPassword() {  
  •         return password;  
  •     }  
  •     public void setPassword(String password) {  
  •         this.password = password;  
  •     }  
  • }  

  2. 对Map类型做转换的类和适配器类
[java] view plaincopyprint?



  • package com.googlecode.garbagecan.cxfstudy.type.sample2;  
  •   
  • import java.util.HashMap;  
  • import java.util.Map;  
  •   
  • import javax.xml.bind.annotation.adapters.XmlAdapter;  
  •   
  • public class MapAdapter extends XmlAdapter<MapConvertor, Map<String, Object>> {  
  •   
  •     @Override  
  •     public MapConvertor marshal(Map<String, Object> map) throws Exception {  
  •         MapConvertor convertor = new MapConvertor();  
  •         for (Map.Entry<String, Object> entry : map.entrySet()) {  
  •             MapConvertor.MapEntry e = new MapConvertor.MapEntry(entry);  
  •             convertor.addEntry(e);  
  •         }  
  •         return convertor;  
  •     }  
  •   
  •     @Override  
  •     public Map<String, Object> unmarshal(MapConvertor map) throws Exception {  
  •         Map<String, Object> result = new HashMap<String, Object>();  
  •         for (MapConvertor.MapEntry e : map.getEntries()) {  
  •             result.put(e.getKey(), e.getValue());  
  •         }  
  •         return result;  
  •     }  
  • }  
  •   
  • package com.googlecode.garbagecan.cxfstudy.type.sample2;  
  •   
  • import java.util.ArrayList;  
  • import java.util.List;  
  • import java.util.Map;  
  •   
  • import javax.xml.bind.annotation.XmlAccessType;  
  • import javax.xml.bind.annotation.XmlAccessorType;  
  • import javax.xml.bind.annotation.XmlType;  
  •   
  • @XmlType(name = "MapConvertor")  
  • @XmlAccessorType(XmlAccessType.FIELD)  
  • public class MapConvertor {  
  •     private List<MapEntry> entries = new ArrayList<MapEntry>();  
  •   
  •     public void addEntry(MapEntry entry) {  
  •         entries.add(entry);  
  •     }  
  •   
  •     public List<MapEntry> getEntries() {  
  •         return entries;  
  •     }  
  •       
  •     public static class MapEntry {  
  •   
  •         private String key;  
  •   
  •         private Object value;  
  •           
  •         public MapEntry() {  
  •             super();  
  •         }  
  •   
  •         public MapEntry(Map.Entry<String, Object> entry) {  
  •             super();  
  •             this.key = entry.getKey();  
  •             this.value = entry.getValue();  
  •         }  
  •   
  •         public MapEntry(String key, Object value) {  
  •             super();  
  •             this.key = key;  
  •             this.value = value;  
  •         }  
  •   
  •         public String getKey() {  
  •             return key;  
  •         }  
  •   
  •         public void setKey(String key) {  
  •             this.key = key;  
  •         }  
  •   
  •         public Object getValue() {  
  •             return value;  
  •         }  
  •   
  •         public void setValue(Object value) {  
  •             this.value = value;  
  •         }  
  •     }  
  • }  

  3. 下面是WebService接口类,注意其中的@XmlJavaTypeAdapter注解部分
[java] view plaincopyprint?



  • package com.googlecode.garbagecan.cxfstudy.type.sample2;  
  •   
  • import java.util.List;  
  • import java.util.Map;  
  •   
  • import javax.jws.WebMethod;  
  • import javax.jws.WebResult;  
  • import javax.jws.WebService;  
  • import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;  
  •   
  • @WebService  
  • public interface UserService {  
  •   
  •     @WebMethod  
  •     @WebResult List<User> getUserList();  
  •   
  •     @WebMethod  
  •     @XmlJavaTypeAdapter(MapAdapter.class)  
  •     @WebResult Map<String, User> getUserMap();  
  • }  

  4. WebService接口实现类
[java] view plaincopyprint?



  • package com.googlecode.garbagecan.cxfstudy.type.sample2;  
  •   
  • import java.util.ArrayList;  
  • import java.util.LinkedHashMap;  
  • import java.util.List;  
  • import java.util.Map;  
  •   
  • public class UserServiceImpl implements UserService {  
  •   
  •     public List<User> getUserList() {  
  •         List<User> userList = new ArrayList<User>();  
  •         for (int i = 0; i < 10; i++) {  
  •             User user = new User();  
  •             user.setId("" + i);  
  •             user.setName("user_" + i);  
  •             user.setPassword("password_" + i);  
  •             userList.add(user);  
  •         }  
  •         return userList;  
  •     }  
  •   
  •     public Map<String, User> getUserMap() {  
  •         Map<String, User> userMap = new LinkedHashMap<String, User>();  
  •         for (int i = 0; i < 10; i++) {  
  •             User user = new User();  
  •             user.setId("" + i);  
  •             user.setName("user_" + i);  
  •             user.setPassword("password_" + i);  
  •             userMap.put(user.getId(), user);  
  •         }  
  •         return userMap;  
  •     }  
  • }  

  5. 最后是一个单元测试类
[java] view plaincopyprint?



  • package com.googlecode.garbagecan.cxfstudy.type.sample2;  
  •   
  • import java.util.List;  
  • import java.util.Map;  
  •   
  • import javax.xml.ws.Endpoint;  
  •   
  • import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;  
  • import org.junit.After;  
  • import org.junit.Assert;  
  • import org.junit.Before;  
  • import org.junit.BeforeClass;  
  • import org.junit.Test;  
  •   
  • public class UserServiceTest {  
  •   
  •     private static final String address = "http://localhost:9000/ws/type/sample2/userService";  
  •       
  •     private UserService userService;  
  •       
  •     @BeforeClass  
  •     public static void setUpBeforeClass() throws Exception {  
  •         Endpoint.publish(address, new UserServiceImpl());  
  •     }  
  •       
  •     @Before  
  •     public void setUp() throws Exception {  
  •         JaxWsProxyFactoryBean factoryBean = new JaxWsProxyFactoryBean();  
  •         factoryBean.setAddress(address);  
  •         factoryBean.setServiceClass(UserService.class);  
  •         Object obj = factoryBean.create();  
  •         userService = (UserService)obj;  
  •     }  
  •   
  •     @After  
  •     public void tearDown() throws Exception {  
  •         userService = null;  
  •     }  
  •   
  •     @Test  
  •     public void testGetUserList() {  
  •         Assert.assertNotNull(userService);  
  •         List<User> users = userService.getUserList();  
  •         Assert.assertNotNull(users);  
  •         Assert.assertEquals(10, users.size());  
  •     }  
  •   
  •     @Test  
  •     public void testGetUserMap() {  
  •         Assert.assertNotNull(userService);  
  •         Map<String, User> users = userService.getUserMap();  
  •         Assert.assertNotNull(users);  
  •         Assert.assertEquals(10, users.size());  
  •     }  
  •   
  • }  

  6. 运行单元测试类验证上面的实现。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-324833-1-1.html 上篇帖子: apache 用rewrite实现二级域名解 下篇帖子: 开源协议:GPL/LGPL/BSD/Apache
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表