在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. 运行单元测试类验证上面的实现。
相关推荐
第一部分介绍关于 SOA 和 Web Services 的初步知识,第二部分介绍Apache CXF 框架的一些基础知识,第三部分重点介绍 Apache CXF 框架的应用,包括 Apache CXF 框架的前端 (Frontends) 应用、 数据绑定 ...
覆盖以下内容:基于JAX-WS规范和CXF自身的前端模式实现,CXF支持的数据绑定(DataBindings),CXF支持的WSDL绑定,CXF支持的传输协议绑定。CXF的调式、配置、日志、发布和工具。CXF实现RESTful服务。CXF对WS-* 的...
Apache CXF Apache CXF Apache CXF Apache CXF Apache CXF Apache CXF Apache CXF Apache CXF Apache CXF
apache cxf 2.1.3 的用户手册
Apache CXF = Celtix + XFire,Apache CXF 的前身叫 Apache CeltiXfire,现在已经正式更名为 Apache CXF 了,以下简称为 CXF。CXF 继承了 Celtix 和 XFire 两大开源项目的精华,提供了对 JAX-WS 全面的支持,并且...
Apache CXF 是一个开放源代码框架,提供了用于方便地构建和开发 Web 服务的可靠基础架构。
apache cxf 3.1.8 java web service 开源框架
Apache CXF Web Service Development
webserviceApache CXF java springboot利用Apache CXF创建webserice接口 Apache CXF 核心架构是以BUS为核心,整合其他组件。 * Bus是CXF的主干, 为共享资源提供一个可配置的场所,作用类似于Spring的...
apache cxf 一个helloworld的例子
Apache CXF Web Service Development Developing+Web+Services+with+Apache+CXF+and+Axis2+(3rd+Edition)
Apache CXF = Celtix + XFire,Apache CXF 的前身叫 Apache CeltiXfire,现在已经正式更名为 Apache CXF 了,以下简称为 CXF。CXF 继承了 Celtix 和 XFire 两大开源项目的精华,提供了对 JAX-WS 全面的支持,并且...
apache-cxf 2.2.8 支持webservice 反正生成服务端代码,附带一个文本文件。希望有需要的小伙伴可以下载来看。
Apache CXF = Celtix + XFire,开始叫 Apache CeltiXfire,后来更名为 Apache CXF 了,以下简称为 CXF。CXF 继承了 Celtix 和 XFire 两大开源项目的精华,提供了对 JAX-WS 全面的支持,并且提供了多种 Binding 、...
java通过cxf实现webservice所需jar包。java通过cxf实现webservice所需jar包。
Apache CXF Web Service Development 源码
Apache Cxf 安全认证,includes some source code to test