• 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

    https://www.cnblogs.com/fanshuyao/

  • 相关阅读:
    简单工厂模式
    原型模式
    特性Attribute
    MVC_Route层层深入
    异步Async
    sql-connectionStrings
    观察者模式(利用委托)
    SqlServer_存储过程
    c语言----程序记录
    c语言基础笔记
  • 原文地址:https://www.cnblogs.com/fanshuyao/p/12156890.html
Copyright © 2020-2023  润新知