`
wake.up
  • 浏览: 13801 次
社区版块
存档分类
最新评论

Apache CXF实战之三 Map类型绑定

    博客分类:
  • cxf
阅读更多

在CXF中,如果Web Service返回类型是Map的时候,比如方法签名如下

 

  1. @WebMethod  
  2. @WebResult Map<String, User> getUserMap();  

此时如果运行程序会得到类似下面的异常

  1. ...  
  2. Caused by: com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 2 counts of IllegalAnnotationExceptions  
  3. java.util.Map is an interface, and JAXB can't handle interfaces.  
  4.     this problem is related to the following location:  
  5.         at java.util.Map  
  6.         at private java.util.Map com.googlecode.garbagecan.cxfstudy.type.sample2.jaxws_asm.GetUserMapResponse._return  
  7.         at com.googlecode.garbagecan.cxfstudy.type.sample2.jaxws_asm.GetUserMapResponse  
  8. java.util.Map does not have a no-arg default constructor.  
  9.     this problem is related to the following location:  
  10.         at java.util.Map  
  11.         at private java.util.Map com.googlecode.garbagecan.cxfstudy.type.sample2.jaxws_asm.GetUserMapResponse._return  
  12.         at com.googlecode.garbagecan.cxfstudy.type.sample2.jaxws_asm.GetUserMapResponse  
  13.     at com.sun.xml.bind.v2.runtime.IllegalAnnotationsException$Builder.check(IllegalAnnotationsException.java:102)  
  14.     at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:472)  
  15.     at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:302)  
  16.     at com.sun.xml.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1136)  
  17.     at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:154)  
  18.     at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:121)  
  19.     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)  
  20.     at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)  
  21.     at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)  
  22.     at java.lang.reflect.Method.invoke(Unknown Source)  
  23.     at javax.xml.bind.ContextFinder.newInstance(Unknown Source)  
  24.     at javax.xml.bind.ContextFinder.newInstance(Unknown Source)  
  25.     at javax.xml.bind.ContextFinder.find(Unknown Source)  
  26.     at javax.xml.bind.JAXBContext.newInstance(Unknown Source)  
  27.     at org.apache.cxf.jaxb.JAXBDataBinding.createContext(JAXBDataBinding.java:560)  
  28.     at org.apache.cxf.jaxb.JAXBDataBinding.createJAXBContextAndSchemas(JAXBDataBinding.java:500)  
  29.     at org.apache.cxf.jaxb.JAXBDataBinding.initialize(JAXBDataBinding.java:320)  
  30.     ... 25 more  
  31. ...  

如果把方法签名改为如下时

 

 

  1. @WebMethod  
  2. @WebResult HashMap<String, User> getUserMap();  

运行程序会发现返回的结果总是一个空的HashMap。

 

 

对于以上问题,此时需要对Map类型做一下数据绑定或者说转换,看下面详细例子

1. 首先是一个实体类

 

  1. package com.googlecode.garbagecan.cxfstudy.type.sample2;  
  2.   
  3. public class User {  
  4.     private String id;  
  5.     private String name;  
  6.     private String password;  
  7.     public String getId() {  
  8.         return id;  
  9.     }  
  10.     public void setId(String id) {  
  11.         this.id = id;  
  12.     }  
  13.     public String getName() {  
  14.         return name;  
  15.     }  
  16.     public void setName(String name) {  
  17.         this.name = name;  
  18.     }  
  19.     public String getPassword() {  
  20.         return password;  
  21.     }  
  22.     public void setPassword(String password) {  
  23.         this.password = password;  
  24.     }  
  25. }  

2. 对Map类型做转换的类和适配器类

 

 

  1. package com.googlecode.garbagecan.cxfstudy.type.sample2;  
  2.   
  3. import java.util.HashMap;  
  4. import java.util.Map;  
  5.   
  6. import javax.xml.bind.annotation.adapters.XmlAdapter;  
  7.   
  8. public class MapAdapter extends XmlAdapter<MapConvertor, Map<String, Object>> {  
  9.   
  10.     @Override  
  11.     public MapConvertor marshal(Map<String, Object> map) throws Exception {  
  12.         MapConvertor convertor = new MapConvertor();  
  13.         for (Map.Entry<String, Object> entry : map.entrySet()) {  
  14.             MapConvertor.MapEntry e = new MapConvertor.MapEntry(entry);  
  15.             convertor.addEntry(e);  
  16.         }  
  17.         return convertor;  
  18.     }  
  19.   
  20.     @Override  
  21.     public Map<String, Object> unmarshal(MapConvertor map) throws Exception {  
  22.         Map<String, Object> result = new HashMap<String, Object>();  
  23.         for (MapConvertor.MapEntry e : map.getEntries()) {  
  24.             result.put(e.getKey(), e.getValue());  
  25.         }  
  26.         return result;  
  27.     }  
  28. }  
  29.   
  30. package com.googlecode.garbagecan.cxfstudy.type.sample2;  
  31.   
  32. import java.util.ArrayList;  
  33. import java.util.List;  
  34. import java.util.Map;  
  35.   
  36. import javax.xml.bind.annotation.XmlAccessType;  
  37. import javax.xml.bind.annotation.XmlAccessorType;  
  38. import javax.xml.bind.annotation.XmlType;  
  39.   
  40. @XmlType(name = "MapConvertor")  
  41. @XmlAccessorType(XmlAccessType.FIELD)  
  42. public class MapConvertor {  
  43.     private List<MapEntry> entries = new ArrayList<MapEntry>();  
  44.   
  45.     public void addEntry(MapEntry entry) {  
  46.         entries.add(entry);  
  47.     }  
  48.   
  49.     public List<MapEntry> getEntries() {  
  50.         return entries;  
  51.     }  
  52.       
  53.     public static class MapEntry {  
  54.   
  55.         private String key;  
  56.   
  57.         private Object value;  
  58.           
  59.         public MapEntry() {  
  60.             super();  
  61.         }  
  62.   
  63.         public MapEntry(Map.Entry<String, Object> entry) {  
  64.             super();  
  65.             this.key = entry.getKey();  
  66.             this.value = entry.getValue();  
  67.         }  
  68.   
  69.         public MapEntry(String key, Object value) {  
  70.             super();  
  71.             this.key = key;  
  72.             this.value = value;  
  73.         }  
  74.   
  75.         public String getKey() {  
  76.             return key;  
  77.         }  
  78.   
  79.         public void setKey(String key) {  
  80.             this.key = key;  
  81.         }  
  82.   
  83.         public Object getValue() {  
  84.             return value;  
  85.         }  
  86.   
  87.         public void setValue(Object value) {  
  88.             this.value = value;  
  89.         }  
  90.     }  
  91. }  

3. 下面是WebService接口类,注意其中的@XmlJavaTypeAdapter注解部分

 

 

  1. package com.googlecode.garbagecan.cxfstudy.type.sample2;  
  2.   
  3. import java.util.List;  
  4. import java.util.Map;  
  5.   
  6. import javax.jws.WebMethod;  
  7. import javax.jws.WebResult;  
  8. import javax.jws.WebService;  
  9. import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;  
  10.   
  11. @WebService  
  12. public interface UserService {  
  13.   
  14.     @WebMethod  
  15.     @WebResult List<User> getUserList();  
  16.   
  17.     @WebMethod  
  18.     @XmlJavaTypeAdapter(MapAdapter.class)  
  19.     @WebResult Map<String, User> getUserMap();  
  20. }  

4. WebService接口实现类

 

 

  1. package com.googlecode.garbagecan.cxfstudy.type.sample2;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.LinkedHashMap;  
  5. import java.util.List;  
  6. import java.util.Map;  
  7.   
  8. public class UserServiceImpl implements UserService {  
  9.   
  10.     public List<User> getUserList() {  
  11.         List<User> userList = new ArrayList<User>();  
  12.         for (int i = 0; i < 10; i++) {  
  13.             User user = new User();  
  14.             user.setId("" + i);  
  15.             user.setName("user_" + i);  
  16.             user.setPassword("password_" + i);  
  17.             userList.add(user);  
  18.         }  
  19.         return userList;  
  20.     }  
  21.   
  22.     public Map<String, User> getUserMap() {  
  23.         Map<String, User> userMap = new LinkedHashMap<String, User>();  
  24.         for (int i = 0; i < 10; i++) {  
  25.             User user = new User();  
  26.             user.setId("" + i);  
  27.             user.setName("user_" + i);  
  28.             user.setPassword("password_" + i);  
  29.             userMap.put(user.getId(), user);  
  30.         }  
  31.         return userMap;  
  32.     }  
  33. }  

5. 最后是一个单元测试类

 

 

  1. package com.googlecode.garbagecan.cxfstudy.type.sample2;  
  2.   
  3. import java.util.List;  
  4. import java.util.Map;  
  5.   
  6. import javax.xml.ws.Endpoint;  
  7.   
  8. import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;  
  9. import org.junit.After;  
  10. import org.junit.Assert;  
  11. import org.junit.Before;  
  12. import org.junit.BeforeClass;  
  13. import org.junit.Test;  
  14.   
  15. public class UserServiceTest {  
  16.   
  17.     private static final String address = "http://localhost:9000/ws/type/sample2/userService";  
  18.       
  19.     private UserService userService;  
  20.       
  21.     @BeforeClass  
  22.     public static void setUpBeforeClass() throws Exception {  
  23.         Endpoint.publish(address, new UserServiceImpl());  
  24.     }  
  25.       
  26.     @Before  
  27.     public void setUp() throws Exception {  
  28.         JaxWsProxyFactoryBean factoryBean = new JaxWsProxyFactoryBean();  
  29.         factoryBean.setAddress(address);  
  30.         factoryBean.setServiceClass(UserService.class);  
  31.         Object obj = factoryBean.create();  
  32.         userService = (UserService)obj;  
  33.     }  
  34.   
  35.     @After  
  36.     public void tearDown() throws Exception {  
  37.         userService = null;  
  38.     }  
  39.   
  40.     @Test  
  41.     public void testGetUserList() {  
  42.         Assert.assertNotNull(userService);  
  43.         List<User> users = userService.getUserList();  
  44.         Assert.assertNotNull(users);  
  45.         Assert.assertEquals(10, users.size());  
  46.     }  
  47.   
  48.     @Test  
  49.     public void testGetUserMap() {  
  50.         Assert.assertNotNull(userService);  
  51.         Map<String, User> users = userService.getUserMap();  
  52.         Assert.assertNotNull(users);  
  53.         Assert.assertEquals(10, users.size());  
  54.     }  
  55.   
  56. }  

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

分享到:
评论

相关推荐

    Apache CXF之结合Spring配置发布WebServices(Aegis数据绑定)

    Aegis数据绑定支持基本的数据类型、集合、Map以及自定义的Java类,为开发者提供了一种灵活的方式来处理Java对象和服务之间的转换。 以下是使用Apache CXF结合Spring发布Web Services(Aegis数据绑定)的基本步骤: ...

    Apache CXF 资料搜集

    5. **Apache CXF入门范例以及对传递ListMap类型的疑惑**:这篇资料可能讨论了在使用CXF时遇到的具体问题,例如如何处理复杂的数据类型,如List&lt;Map, Object&gt;&gt;。在Web服务中,复杂类型的序列化和反序列化可能需要特别...

    cxf-webservice复杂类型

    在Web服务领域,Apache CXF是一个广泛使用的开源框架,它允许开发者创建和消费各种类型的Web服务,包括处理复杂的类型数据。本主题将深入探讨CXF如何处理像Map这样的Java集合类,以及其他不能直接通过标准XML Schema...

    04.使用CXF处理JavaBean式的复合类型和List集合类型的形参和返回值

    在本文中,我们将深入探讨如何使用Apache CXF框架来处理JavaBean式的复合类型以及List集合类型的参数和返回值。CXF是一个开源的、强大的Web服务框架,它支持多种Web服务标准,包括SOAP、RESTful等,并且允许开发者以...

    CXF入门.rar

    Apache CXF入门范例以及对传递ListMap类型的疑惑】中,可能会详细解释如何创建和调用一个使用CXF的Web服务,同时也可能讨论了在处理复杂数据类型如List&lt;Map, Object&gt;&gt;时遇到的问题和解决方案。通常,CXF允许你通过...

    CXF关于Aegis的简单示例

    Aegis支持基本数据类型、集合、Map、JavaBeans等,但不包括Java的复杂类型如注解或泛型。 2. **Spring集成**:在提供的文件名称"Aegis_Spring_Client"中,我们可以推断出示例可能涉及到Spring框架的集成。Spring是...

    详细介绍XFire和CXF还有AXIS开发

    本篇文章将深入探讨三个流行的Java Web Service框架:XFire、CXF和Axis,它们都是用于构建和消费Web服务的重要工具。 1. **XFire**: XFire是早期的Web服务实现,它提供了一个轻量级、高性能的框架,支持SOAP 1.1...

    Dubbo面试.pdf

    3. webservice协议:基于WebService协议实现远程调用,通过集成Apache CXF框架提供了和原生WebService的互操作性。适用于系统集成和跨语言调用。这种协议使用HTTP协议传输,支持同步通信,能够与其他使用标准...

    wsdl4j 解析wsdl 文件

    2. **服务生成器**:工具或框架(如Axis,CXF等)使用WSDL4J自动生成服务客户端或服务器端代码。 3. **测试工具**:测试框架可能利用WSDL4J检查服务是否符合WSDL定义。 ### 总结 WSDL4J是处理WSDL文档的关键工具,...

    ASP EXCEL导入SQL

    它们的新的项目分别是ApacheCXF和Axis2.Java语言也制定关于REST网络服务规范:JAX-RS:JavaAPIforRESTfulWebServices(JSR311)。相信还会出现更多与REST相关的激动人心的信息。  REST与AJAX技术  尽管AJAX技术的...

Global site tag (gtag.js) - Google Analytics