cxf Map参数,cxf webservice复杂参数
cxf Map参数,cxf webservice复杂参数
================================
©Copyright 蕃薯耀 2020-01-06
https://www.cnblogs.com/fanshuyao/
一、问题描述:
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 蕃薯耀 2020-01-06
今天越懒,明天要做的事越多。