在CXF中,如果Web Service返回类型是Map的时候,比如方法签名如下
- @WebMethod
- @WebResult Map<String, User> getUserMap();
此时如果运行程序会得到类似下面的异常
- ...
- 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
- ...
如果把方法签名改为如下时
- @WebMethod
- @WebResult HashMap<String, User> getUserMap();
运行程序会发现返回的结果总是一个空的HashMap。
对于以上问题,此时需要对Map类型做一下数据绑定或者说转换,看下面详细例子
1. 首先是一个实体类
- 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类型做转换的类和适配器类
- 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注解部分
- 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接口实现类
- 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. 最后是一个单元测试类
- 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. 运行单元测试类验证上面的实现。
相关推荐
Aegis数据绑定支持基本的数据类型、集合、Map以及自定义的Java类,为开发者提供了一种灵活的方式来处理Java对象和服务之间的转换。 以下是使用Apache CXF结合Spring发布Web Services(Aegis数据绑定)的基本步骤: ...
5. **Apache CXF入门范例以及对传递ListMap类型的疑惑**:这篇资料可能讨论了在使用CXF时遇到的具体问题,例如如何处理复杂的数据类型,如List<Map, Object>>。在Web服务中,复杂类型的序列化和反序列化可能需要特别...
在Web服务领域,Apache CXF是一个广泛使用的开源框架,它允许开发者创建和消费各种类型的Web服务,包括处理复杂的类型数据。本主题将深入探讨CXF如何处理像Map这样的Java集合类,以及其他不能直接通过标准XML Schema...
在本文中,我们将深入探讨如何使用Apache CXF框架来处理JavaBean式的复合类型以及List集合类型的参数和返回值。CXF是一个开源的、强大的Web服务框架,它支持多种Web服务标准,包括SOAP、RESTful等,并且允许开发者以...
Apache CXF入门范例以及对传递ListMap类型的疑惑】中,可能会详细解释如何创建和调用一个使用CXF的Web服务,同时也可能讨论了在处理复杂数据类型如List<Map, Object>>时遇到的问题和解决方案。通常,CXF允许你通过...
Aegis支持基本数据类型、集合、Map、JavaBeans等,但不包括Java的复杂类型如注解或泛型。 2. **Spring集成**:在提供的文件名称"Aegis_Spring_Client"中,我们可以推断出示例可能涉及到Spring框架的集成。Spring是...
本篇文章将深入探讨三个流行的Java Web Service框架:XFire、CXF和Axis,它们都是用于构建和消费Web服务的重要工具。 1. **XFire**: XFire是早期的Web服务实现,它提供了一个轻量级、高性能的框架,支持SOAP 1.1...
3. webservice协议:基于WebService协议实现远程调用,通过集成Apache CXF框架提供了和原生WebService的互操作性。适用于系统集成和跨语言调用。这种协议使用HTTP协议传输,支持同步通信,能够与其他使用标准...
2. **服务生成器**:工具或框架(如Axis,CXF等)使用WSDL4J自动生成服务客户端或服务器端代码。 3. **测试工具**:测试框架可能利用WSDL4J检查服务是否符合WSDL定义。 ### 总结 WSDL4J是处理WSDL文档的关键工具,...
它们的新的项目分别是ApacheCXF和Axis2.Java语言也制定关于REST网络服务规范:JAX-RS:JavaAPIforRESTfulWebServices(JSR311)。相信还会出现更多与REST相关的激动人心的信息。 REST与AJAX技术 尽管AJAX技术的...