cxf处理一些Map等复杂类型

前面讲的一些都是简单类型,cxf都支持。但是有些复杂类型,cxf是不支持,比如常用的Map类型;

下面我们在前面的实例基础上在加一个方法,比如我们现在有个需求,获取所有用用户以及对应的每个用户所有角色信息;

服务器端:

HelloWorld接口加方法:

/**
	 * 获取所有用户以及对应的角色
	 * @return
	 */
	public Map<String,List<Role>> getRoles();

HelloWorldImpl实现类加方法实现:

public Map<String, List<Role>> getRoles() {
		Map<String,List<Role>> map=new HashMap<String,List<Role>>();
		List<Role> roleList1=new ArrayList<Role>();
		roleList1.add(new Role(1,"技术总监"));
		roleList1.add(new Role(2,"架构师"));
		map.put("java1234", roleList1);
		List<Role> roleList2=new ArrayList<Role>();
		roleList2.add(new Role(1,"程序员"));
		map.put("jack", roleList2);
		return map;
	}

然后我们启动Server类:发现报错:

这个报错信息说,不支持该类型;

这里我们有好几种解决方案,这里我们用最常用的一种,使用适配器,把cxf不能接受的类型通过适配器,转能接受的类型。

我们使用@XmlJavaTypeAdapter注解,加在接口定义上,完整接口代码如下:

package com.java1234.webservice;

import java.util.List;
import java.util.Map;

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

import com.java1234.adapter.MapAdapter;
import com.java1234.entity.Role;
import com.java1234.entity.User;

@WebService
public interface HelloWorld {

	public String say(String str);

	public List<Role> getRoleByUser(User user);

	/**
	 * 获取所有用户以及对应的角色
	 * @return
	 */
	@XmlJavaTypeAdapter(MapAdapter.class)
	public Map<String,List<Role>> getRoles();
}

这里参数需要一个实现了XmlAdapter类的适配器类;

package com.java1234.adapter;

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

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

import com.java1234.entity.Role;

/**
 * Map适配器
 * @author Administrator
 *
 */
public class MapAdapter extends XmlAdapter<MyRole[], Map<String,List<Role>>>{

	/**
	 * 适配转换  MyRole[] -> Map<String, List<Role>>
	 */
	@Override
	public Map<String, List<Role>> unmarshal(MyRole[] v) throws Exception {
		Map<String, List<Role>> map=new HashMap<String,List<Role>>();
		for(int i=0;i<v.length;i++){
			MyRole r=v[i];
			map.put(r.getKey(), r.getValue());
		}
		return map;
	}

	/**
	 * 适配转换  Map<String, List<Role>> -> MyRole[]
	 */
	@Override
	public MyRole[] marshal(Map<String, List<Role>> v) throws Exception {
		MyRole[] roles=new MyRole[v.size()];
		int i=0;
		for(String key:v.keySet()){
			roles[i]=new MyRole();
			roles[i].setKey(key);
			roles[i].setValue(v.get(key));
			i++;
		}
		return roles;
	}

}

这里的话XmlAdapter要加两个参数,XmlAdapter<ValueType,BoundType>

ValueType是cxf能接收的类型,这里我用了数组;

BoundType是cxf不能接受的类型,也就是我例子里的需求的Map类型;

这里大家会看到,还有一个MyRole自定义类型,key:value。我们搞成两个属性,具体实现如下:

package com.java1234.adapter;

import java.util.List;

import com.java1234.entity.Role;

/**
 * 自定义实体 cxf能接受
 * @author Administrator
 *
 */
public class MyRole {

	private String key;
	private List<Role> value;

	public String getKey() {
		return key;
	}
	public void setKey(String key) {
		this.key = key;
	}
	public List<Role> getValue() {
		return value;
	}
	public void setValue(List<Role> value) {
		this.value = value;
	}

}

OK 这样就行了。我们运行Server类,发布webservice接口:

然后就到了webservice客户端,我们用wsdl2java工具生成下最新代码,具体过程前面讲过,这里不重复讲:

生成代码如下:

我们修改下Client类:

package com.java1234.webservice;

import java.util.List;

public class Client {

	public static void main(String[] args) {
		HelloWorldService service=new HelloWorldService();
		HelloWorld helloWorld=service.getHelloWorldPort();
		//System.out.println(helloWorld.say("java1234"));
		/*User user=new User();
		user.setUserName("jack");
		user.setPassword("123456");
		List<Role> roleList=helloWorld.getRoleByUser(user);
		for(Role role:roleList){
			System.out.println(role.getId()+","+role.getRoleName());
		}*/
		MyRoleArray array=helloWorld.getRoles();
		List<MyRole> roleList=array.item;
		for(int i=0;i<roleList.size();i++){
			MyRole my=roleList.get(i);
			System.out.print(my.key+":");
			for(Role r:my.value){
				System.out.print(r.getId()+","+r.getRoleName()+" ");
			}
			System.out.println();
		}
	}
}

运行下:

OK,这样就实现了复杂类型的调用;

完整代码:http://pan.baidu.com/s/1kTUseOZ

原文地址:https://www.cnblogs.com/grimm/p/12359146.html

时间: 2024-08-30 12:24:14

cxf处理一些Map等复杂类型的相关文章

【WebService】CXF处理javaBean等复合类型以及Map等复杂类型的数据

WebService系列文章: [WebService]带你走进webservice的世界 [WebService]自定义WebService服务及其调用 [WebService]wsdl配置详解以及使用注解修改wsdl配置 在实际中除了传入一些基本的参数以外,还需要传入一些类似于javaBean等复合类型,或者Map等复杂类型的数据,这一篇博文主要来写两个demo,模拟一下CXF处理这类数据的过程. 1. CXF处理javaBean等复合类型的数据 客户端提交一个数据过去,要检查权限,比如是管

学习webservice之cxf(5):cxf处理map等复杂类型

Caused by: com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions java.util.List是接口, 而 JAXB 无法处理接口. this problem is related to the following location: at java.util.List at private java.util.Map com.r

转: 在hibernate中查询使用list,map定制返回类型

在使用hibernate进行查询时,使用得最多的还是通过构建hql进行查询了.在查询的过程当中,除使用经常的查询对象方法之外,还会遇到查询一个属性,或一组聚集结果的情况.在这种情况下,我们通常就需要对返回的结构进行处理.    一般情况下,我们通过构建hql,并通过设置query的resultTransformer来定制返回结果的类型,一般设置为map属性,如下所示: 1 Query query = session.createQuery("hql"); 2 query.setResu

map以自定义类型当Key

关于map的定义: template < class Key, class T, class Compare = less<Key>, class Allocator = allocator<pair<const Key,T> > > class map; 第一个template参数被当做元素的key,第二个template参数被当作元素的value.Map的元素型别Key和T,必须满足以下两个条件:1.key/value必须具备assignable(可赋值

Golang 使用Map构建Set类型的实现方法

前言 本篇主要给大家讲述了如何利用Go语言的语法特性实现Set类型的数据结构,分享出来供大家参考学习,话不多说了,来一起看看详细的介绍吧. 需求 对于Set类型的数据结构,其实本质上跟List没什么多大的区别.无非是Set不能含有重复的Item的特性,Set有初始化.Add.Clear.Remove.Contains等操作.接下来看具体的实现方式分析吧. 实现 仍然按照已有的编程经验来联想如何实现基本Set功能,在Java中很容易知道HashSet的底层实现是HashMap,核心的就是用一个常量

spring map获取同类型的bean

今天看博客怎么减少if else 方法, 才发现spring 还有很多功能我没有用到,以后真的得花时间学学spring,今天学到的东西如下: 1.定义一个接口 store public interface Store { void handle(); } 2.定义两个类 @Service("storeA") public class StoreA implements Store { @Override public void handle() { } @Override public

Mybatis之foreach用法----List、Array、Map三种类型遍历

在mybatis的xml文件中构建动态sql语句时,经常会用到标签遍历查询条件.特此记录下不同情况下书写方式!-------仅供大家参考------ 1. foreach元素的属性 collection: 需做foreach(遍历)的对象,作为入参时,list.array对象时,collection属性值分别默认用"list"."array"代替,Map对象没有默认的属性值.但是,在作为入参时可以使用@Param("keyName")注解来设置自

MyBatis 返回Map&lt;String,Object&gt;类型

<resultMap type="map" id="stringMap"> <result property="contentIntr" column="contentIntr" javaType="string" /> </resultMap> <!-- 导出所有数据 --> <select id="exportAll" resul

通过递归将list&lt;Map&lt;String,Object&gt;&gt;类型的数据转换为tree组件可识别的json数据

public static JSONObject getDeptTree(List<Map<String,Object>> list,String id) throws JSONException{ JSONObject json=new JSONObject(); JSONArray jsons=new JSONArray();//children数组 for (Map<String, Object> map : list) { String id=map.get(&