文档章节

Map等CXF无法自动转换的复合数据类型的形参和返回值的处理

蜡笔小小小新
 蜡笔小小小新
发布于 2015/12/28 22:18
字数 721
阅读 30
收藏 5

CXF并非能处理任何类型,向Map<String,Object>这样的复杂类型不能帮助开发人员处理,需要开发人员自行处理.


服务端接口和服务组件:

package com.lin.ws.intf;

import java.util.Map;

import javax.jws.WebService;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

import com.lin.ws.entity.Order;
import com.lin.ws.entity.User;
import com.lin.ws.util.MapXmlHandler;

/**
 * 服务的接口
 * @author lin
 *
 */
//暴露的事这个接口
@WebService
public interface IUserService {
    
    public void addUser(User user);
    
    public User getUserById(Integer id);
    
    public Integer countOfUser();
    
    public Map<String,Order> getOrdersByUser(User user); 

}


package com.lin.ws.impl;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;

import javax.jws.WebService;

import com.lin.ws.entity.Order;
import com.lin.ws.entity.User;
import com.lin.ws.intf.IUserService;

/**
 * 服务实现类
 * @author lin
 *
 */
//注解指定该服务的接口,和服务的名称
@WebService(endpointInterface="com.lin.ws.intf.IUserService",serviceName="UserService")
public class UserServiceImpl implements IUserService {

    @Override
    public void addUser(User user) {
        
        System.out.println("Add a user:"+user.toString());
    }

    @Override
    public User getUserById(Integer id) {
        
        System.out.println("Get a user by id:"+id);
        
        return null;
    }

    @Override
    public Integer countOfUser() {
        
        Integer count = (new Random()).nextInt();
        
        System.out.println("Return the count of users: "+count);
        
        return count;
    }

    @Override
    public Map<String, Order> getOrdersByUser(User user) {
        
        if(user != null)
        {
            Map<String, Order> orders = new HashMap<>();
            orders.put("order1", new Order(1, "order1", user.getId()));
            orders.put("order2", new Order(2, "order2", user.getId()));
            orders.put("order3", new Order(3, "order3", user.getId()));
            
            return orders;
        }
        return null;
    }

}


发布服务后会报错:


这实际上CXF无法处理接口方法中的那个Map<String,Order>类型:

public Map<String,Order> getOrdersByUser(User user);



那么,需要将Map<String,Order>转化成CXF能帮助处理的类型,在该类型前面加上@XmlJavaTypeAdapter这个annotation

package com.lin.ws.intf;

import java.util.Map;

import javax.jws.WebService;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

import com.lin.ws.entity.Order;
import com.lin.ws.entity.User;
import com.lin.ws.util.MapXmlHandler;

/**
 * 服务的接口
 * @author lin
 *
 */
//暴露的事这个接口
@WebService
public interface IUserService {
    
    public void addUser(User user);
    
    public User getUserById(Integer id);
    
    public Integer countOfUser();
    
    //CXF 框架无法处理Map<String,Order>类型,需要工程师自行处理
    //需要提供一个转换器,把CXF无法处理的类型转化成CXF可以处理的类型
    //value是需要提供的转换器
    public @XmlJavaTypeAdapter(MapXmlHandler.class) Map<String,Order> getOrdersByUser(User user); 

}


@XmlJavaTypeAdapter的api:


默认参数是一个类型转换器,需要开发人员自行实现:


一个可以和map转化的类:

package com.lin.ws.entity;

import java.util.ArrayList;
import java.util.List;

public class StringOrder {
    
    private List<Entry> entries = new ArrayList<>();
    
    public List<Entry> getEntries() {
        return entries;
    }

    public void setEntries(List<Entry> entries) {
        this.entries = entries;
    }

    public static class Entry{
        
        private String key;
        private Order value;
        
        public Entry() {
            super();
        }

        public Entry(String key, Order value) {
            super();
            this.key = key;
            this.value = value;
        }

        public String getKey() {
            return key;
        }

        public void setKey(String key) {
            this.key = key;
        }

        public Order getValue() {
            return value;
        }

        public void setValue(Order value) {
            this.value = value;
        }
    }

}


转化器类:

package com.lin.ws.util;

import java.util.HashMap;
import java.util.Map;

import javax.xml.bind.annotation.adapters.XmlAdapter;

import com.lin.ws.entity.Order;
import com.lin.ws.entity.StringOrder;
import com.lin.ws.entity.StringOrder.Entry;

/**
 * StringOrder与,Map<String,Order>相互转换
 * @author lin
 *
 */
public class MapXmlHandler extends XmlAdapter<StringOrder, Map<String, Order>> {

    @Override
    public Map<String, Order> unmarshal(StringOrder v) throws Exception {
        
        //将StringOrder转化成Map<String,Order>
        Map<String, Order> map = new HashMap<String, Order>();
        
        for(StringOrder.Entry entry : v.getEntries())
        {
            map.put(entry.getKey(), entry.getValue());
        }
        return map;
    }

    @Override
    public StringOrder marshal(Map<String, Order> v) throws Exception {
        
        //将Map<String,Order>转化成StringOrder
        StringOrder stringOrder = new StringOrder();
        
        for(String key : v.keySet())
        {
            stringOrder.getEntries().add(new Entry(key, v.get(key)));
        }
        
        return stringOrder;
    }

}


重新发布服务,OK,解决这个问题.

© 著作权归作者所有

共有 人打赏支持
蜡笔小小小新
粉丝 32
博文 114
码字总数 75210
作品 0
深圳
后端工程师
Web Service 那点事儿(4)—— 使用 CXF 开发 REST 服务

现在您已经学会了如何使用 CXF 开发基于 SOAP 的 Web 服务,也领略了 Spring + CXF 这个强大的组合,如果您错过了这精彩的一幕,请回头看看这篇吧: [Web Service 那点事儿(2) —— 使用 ...

黄勇
2014/07/23
0
43
使用CXF开发RestFul WebService问题解决方案

最近在项目中,因为几个系统自己需要数据交换,所以采用进来都比较流行的RestFul风格WebService,实现框架采用apache的cxf,apache的东西一直以来都是比较的好用,回话少说,进入正题。 首先...

xdev
2013/05/18
0
3
新手初识webservice-实践篇

理论背景:《新手初识webservice-理论篇》http://my.oschina.net/achi/blog/52766 编程语言:Java 必要技能:JavaWeb,MVC,Spring IOC 情景假设:你刚用Java做了个网上店铺,用了servlet,MVC...

路飞
2012/04/12
0
5
CXF开发webservice

什么是CXF: Apache CXF = Celtix + Xfire 支持多种协议: SOAP1.1,1.2 XML/HTTP CORBA(Common Object Request Broker Architecture公共对象请求代理体系结构,早期语言使用的WS。 C,c++,C#...

包包大人
2014/04/04
0
0
企业级生产就绪 SOAP-Web 服务 - cxf-spring-boot-starter

cxf-spring-boot-starter 是由Spring Boot和Apache CXF提供支持的企业级生产就绪SOAP-Web服务。 功能包括: 使用来自WSDL / XSD的JAX-B生成所有必需的Java类(使用补充的Maven插件cxf-sprin...

匿名
07/23
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

7月13日任务 for、while、break跳出、ontinue结束、exit退出

20.10 for循环 语法:for 变量名 in 条件; do …; done 案例1:计算1到100的和 #!/bin/bashsum=0for i in `seq 1 100`do    sum=$[$sum+$i]    echo $idoneecho $sum 案例2...

吕湘颖
38分钟前
0
0
qemu增量镜像的好处

可以快速恢复,相当于快照的功能。

simpower
46分钟前
0
0
Python3_Appium_QQ 实战

Python3_Appium实战 -海盐 APPium移动自动化测试 样例中 测试的 app 使用的是 QQ; Appium介绍 Appium 是一个自动化测试开源工具,支持 iOS 平台和 Android 平台上的原生应用,web 应用和混合...

海盐宝宝
46分钟前
0
0
内网穿透利器-ngrok的图文安装

使用场景: 在做微信开发或是调银行或支付宝等支付系统的时候,本地想联调但是对方需要可以访问的域名或是外网IP才可以。但是,在本地如果不在路由器上做映射或是公司没有固定的外网IP。这种...

中凯_凯哥java
51分钟前
4
1
归约与分组 - 读《Java 8实战》

区分Collection,Collector和collect 代码中用到的类与方法用红框标出,可从git库中查看 收集器用作高级归约 // 按货币对交易进行分组Map<Currency, List<Transaction>> currencyListMap = g...

yysue
51分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部