欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

cxf Map参数,cxf webservice复杂参数

程序员文章站 2022-04-04 12:30:46
...

cxf Map参数,cxf webservice复杂参数

 

================================

©Copyright 蕃薯耀 2018年5月18日

http://fanshuyao.iteye.com/

 

一、问题描述:

cxf 的服务方法中,是不能使用java.util.Map作为参数的,因为本身不支持转换

 

二、解决方案

1、自定义对象实体参数,然后再通过自定义适配器进行转换,该适配器需要继承XmlAdapter类,实现里面2个方法,如下:

 

public class RowImplAdapter extends XmlAdapter<AdapterData, RowImpl>{
	
	@Override
	public RowImpl unmarshal(AdapterData adapterData) throws Exception {
		RowImpl rowImpl = new RowImpl();
		List<AdapterEntity> entities = adapterData.getEntities();
		for (AdapterEntity adapterEntity : entities) {
			rowImpl.addColumn(adapterEntity.getKey(), adapterEntity.getValue());
		}
		return rowImpl;
	}

	@Override
	public AdapterData marshal(RowImpl rowImpl) throws Exception {
		AdapterData adapterData = new AdapterData();
		@SuppressWarnings("unchecked")
		Set<Map.Entry<String, Object>> set = rowImpl.entrySet();
		for (Map.Entry<String, Object> entry : set) {
			adapterData.getEntities().add(new AdapterEntity(entry.getKey(), entry.getValue()));
		}
		return adapterData;
	}
	
}
 

 

AdapterData:

 

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

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlType;

@XmlType(name="AdapterData")
@XmlAccessorType(XmlAccessType.FIELD)
public class AdapterData {
	private List<AdapterEntity> entities = new ArrayList<AdapterEntity>();

	public List<AdapterEntity> getEntities() {
		return entities;
	}

	public void setEntities(List<AdapterEntity> entities) {
		this.entities = entities;
	}
	
}
 

 

AdapterEntity:(其实这个实体就是仿照Map的键值对形式)

 

public class AdapterEntity{
	private String key;
	private Object value;
	public AdapterEntity() {
		super();
	}
	public AdapterEntity(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;
	}

}
 

 

2、webservice服务方法需要在转换的参数添加一个注解(@XmlJavaTypeAdapter),如下

 这个注解是加在接口的方法上,不是在实体的方法。

@WebMethod (operationName="xxx")
	public String xxx(@WebParam @XmlJavaTypeAdapter(RowImplAdapter.class) RowImpl rowImpl) throws Exception; 

 

3、客户端使用JaxWsDynamicClientFactory 调用

public void findPlaceNameList(HttpServletRequest request,HttpServletResponse response) throws Exception{
		String result = "{}";
		try {
			Row row = parseRequestParametersToRow(request);
			
			Properties  prop = PropertiesUtils.read("placeNameServerURL.properties");
			String ghyw_url = PropertiesUtils.readKeyValue(prop, "ghyw_url");
			String webservice_prefix = PropertiesUtils.readKeyValue(prop, "webservice_prefix");
			String webservice_url = PropertiesUtils.readKeyValue(prop, "webservice_url");
			
			JaxWsDynamicClientFactory clientFactory = JaxWsDynamicClientFactory.newInstance();
			Client client = clientFactory.createClient(ghyw_url + webservice_prefix +webservice_url);
			Object[] results = client.invoke("webservice方法名", CxfAdapterUtils.rowToAdapterData(row));
			if(results != null){
				result = (String) results[0];
				System.out.println("result="+result);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally{
			writeJson(response, result);
		}
	}

 

 4、客户端调用时,参数需要转换,即把Row对象转换成AdapterData对象,然后再传过去

CxfAdapterUtils.rowToAdapterData(row)对应的工具类,如下:

import java.util.Map;
import java.util.Set;

import com.plan.commons.Row;
import com.plan.commons.RowImpl;

/**
 * cxf 适配器工具 类
 *
 */
public class CxfAdapterUtils {

	/**
	 * 将Row转换成AdapterData对象
	 * @param row
	 * @return
	 */
	public static AdapterData rowToAdapterData(Row row){
		AdapterData adapterData = new AdapterData();
		@SuppressWarnings("unchecked")
		Set<Map.Entry<String, Object>> set = row.entrySet();
		for (Map.Entry<String, Object> entry : set) {
			adapterData.getEntities().add(new AdapterEntity(entry.getKey(), entry.getValue()));
		}
		return adapterData;
	};
}

 

 

三、总结

其实这样转换挺复杂的,感觉吃力不讨好。

个人觉得还是使用json工具类,把需要传递过去的复杂对象转换成json后,然后以字符串的形式传递过去,服务端通过json工具再解析成对象,这样方便很多,也不用太折腾。

 

================================

©Copyright 蕃薯耀 2018年5月18日

http://fanshuyao.iteye.com/