cxf Map参数,cxf webservice复杂参数
================================
©Copyright 蕃薯耀 2018年5月18日
http://fanshuyao.iteye.com/
一、问题描述:
cxf 的服务方法中,是不能使用java.util.Map作为参数的,因为本身不支持转换
二、解决方案
1、自定义对象实体参数,然后再通过自定义适配器进行转换,该适配器需要继承XmlAdapter类,实现里面2个方法,如下:
public class RowImplAdapter extends XmlAdapter{
@Override
public RowImpl unmarshal(AdapterData adapterData) throws Exception {
RowImpl rowImpl = new RowImpl();
List 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> set = rowImpl.entrySet();
for (Map.Entry 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 entities = new ArrayList();
public List getEntities() {
return entities;
}
public void setEntities(List 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> set = row.entrySet();
for (Map.Entry entry : set) {
adapterData.getEntities().add(new AdapterEntity(entry.getKey(), entry.getValue()));
}
return adapterData;
};
}
三、总结
其实这样转换挺复杂的,感觉吃力不讨好。
个人觉得还是使用json工具类,把需要传递过去的复杂对象转换成json后,然后以字符串的形式传递过去,服务端通过json工具再解析成对象,这样方便很多,也不用太折腾。
================================
©Copyright 蕃薯耀 2018年5月18日
http://fanshuyao.iteye.com/