文档章节

Apache CXF实战之八 Map类型绑定

DavidBao
 DavidBao
发布于 2015/05/31 21:46
字数 888
阅读 7
收藏 0

本文链接:http://blog.csdn.net/kongxx/article/details/7544640

Apache CXF实战之一 Hello World Web Service

Apache CXF实战之二 集成Sping与Web容器

Apache CXF实战之三 传输Java对象

Apache CXF实战之四 构建RESTful Web Service

Apache CXF实战之五 压缩Web Service数据

Apache CXF实战之六 创建安全的Web Service

Apache CXF实战之七 使用Web Service传输文件

在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. 运行单元测试类验证上面的实现。





本文转载自:http://blog.csdn.net/kongxx/article/details/7544640

DavidBao
粉丝 113
博文 213
码字总数 126729
作品 0
昌平
私信 提问
apache cxf map问题

apache cxf 可以直接使用map吗。我看好多资料都说cxf不能直接支持map类型,必须写一个适配器来对map类型进行绑定。 但是我在测试中,把cxf 2.7.14的JAR包全部导入的情况下,不需要写map的适配...

啊一
2014/12/27
92
0
Apache CXF 和 Spring 开发 Web Service 1

正文 为什么使用CXF 本文段摘录自 http://www.ibm.com/developerworks/cn/webservices/ws-pojo-springcxf/index.html Apache CXF 是一个开放源代码框架,提供了用于方便地构建和开发 Web 服务...

洋葱94
2015/12/04
274
0
Apache CXF 2.4.0 发布

Apache CXF一个开源的Service框架,它实现了JCP与Web Service中一些重要标准。CXF简化了构造,集成,面 向服务架构(SOA)业务组件与技术的灵活复用。在CXF中,Service使用WSDL标准定义并能够使...

红薯
2011/04/19
2.6K
0
Apache CXF 3.1.15 发布,开源的 Service 框架

Apache CXF 3.1.15 发布了。Apache CXF一个开源的Service框架,它实现了JCP与Web Service中一些重要标准。CXF简化了构造,集成,面向服务架构(SOA)业务组件与技术的灵活复用。 更新内容: Bu...

淡漠悠然
2018/03/14
874
1
cxf webservice整合spring

前端建模:CXF 提供了前端建模的概念,允许您使用不同的前端 API 来创建 Web 服务。API 允许您使用简单的工厂 Bean 并通过 JAX-WAS 实现来创建 Web 服务。它还允许您创建动态 Web 服务客户端...

尚浩宇
2015/06/24
202
0

没有更多内容

加载失败,请刷新页面

加载更多

微课程 | 第六课《复杂查询》

https://v.youku.com/v_show/id_XNDQ2MDAzOTE2MA==.html 上一期我们通过基本拆分算法,展示基本配置是什么样的。现在来介绍下 dble 其他的一些功能。 dble 查询流程图 首先基本的 DML 我们已...

爱可生
14分钟前
2
0
在pad上点击输入框调出小键盘

在页面加载时加入: var asForm = System.Windows.Automation.AutomationElement.FromHandle(this.Handle); private void frmPadWIPCallMaterial_Load(object sender, Ev......

_Somuns
15分钟前
2
0
服务身份授权OpenIAM

使用OpenIAM作为服务间统一身份和资源授权的解决方案。它基于AWS的IAM模型设计,为服务接口提供统一管理了身份认证和资源授权管控能力。服务提供方可通过OpenIAM来实现接口访问的细粒度管控。...

ZH-JSON
21分钟前
2
0
远程调用----HttpClient连接池

学连接池首先要明白: 1.http连接池也不是万能的,过多的长连接会占用服务器资源,导致其他服务受阻 2.http连接池值适用于请求是经常访问同一主机(或同一接口)的情况下 3.并发数不高的情况下资源...

苗小喵
29分钟前
3
0
mybatis_plus一对一实体映射

场景:查询中间表对应的用户和角色,这里一条中间表数据分别只对应一个用户和一个角色。当然一般不会有这样的需求,这里只是举例一对一关系. 一、数据结构 1、用户表 2、角色表 3、中间表 二...

一个yuanbeth
35分钟前
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部