加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

WebService 工具类

发布时间:2020-12-16 23:20:50 所属栏目:安全 来源:网络整理
导读:经常使用WebService来调接口的工具类: /prepre name="code" class="java"package com.thunisoft.hlwzbdb.mgr.business.ajgl.record;import java.net.MalformedURLException;import java.net.URL;import java.util.Arrays;import java.util.HashMap;import j
经常使用WebService来调接口的工具类:
</pre><pre name="code" class="java">package com.thunisoft.hlwzbdb.mgr.business.ajgl.record;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.codehaus.xfire.client.Client;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

/**
 * webservice 工具类
 * 
 * 该工具类使用了Xfire单例的方式,问了解决cas中webservice访问慢的问题;
 * 
 * 目前Xfire单例方式使用可能会有多线程并发问题,但是考虑实际业务场景,用户并发的可能性比较小,所以暂时提取公用工具类。
 * 
 * 后续计划加入webservice客户端实例池解决并发问题
 * 

 * 
 */
public class WSUtil {

    /**
     * 请求成功
     */
    final public static String WSCALL_STATUS_SUCCESS = "1";

    /**
     * 无权限
     */
    final public static String WSCALL_STATUS_NORIGHT = "2";

    /**
     * 参数错误
     */
    final public static String WSCALL_STATUS_BADPARAMS = "3";

    /**
     * 异常
     */
    final public static String WSCALL_STATUS_EXCEPTION = "4";

    /**
     * 日志
     */
    private static final Log logger = LogFactory.getLog(WSUtil.class);

    /**
     * 生成代理客户端
     * 
     * 
     */
    private final static class ProxyClient extends Client {
        /**
         * 构造器
         * 
         * @param url
         * @throws Exception
         */
        private ProxyClient(URL url) throws Exception {
            super(url);
        }

        @Override
        public void close() {
            logger.warn("单例模式的webservice客户端,不需要关闭!");
        }

        /**
         * 真实关闭
         */
        public void reallyClose() {
            super.close();
        }
    }

    /**
     * webservice 客户端连接池
     * 
     * @author yangkai
     * 
     */
    private static class ClientPool {

        /**
         * 连接池缓存
         */
        private static Map<String,ClientPool> pools = new HashMap<String,ClientPool>();

        /**
         * 池对象
         */
        private Client[] pool;

        /**
         * 连接URL
         */
        private String url;

        /**
         * 当前连接标记
         */
        private int current;

        /**
         * 构造器,初始化连接池
         * 
         * @param url
         *            webservice地址
         * @param size
         *            连接池大小
         */
        public ClientPool(String url,int size) {
            this.url = url;
            pool = new Client[size];
            current = 0;
            pools.put(url,this);
        }

        /**
         * 从连接池中获取一个连接
         * 
         * @return
         */
        public synchronized Client get() {
            Client client = null;
            synchronized (this) {
                if (current >= 0) {
                    client = pool[current--];
                }
            }
            System.out.println("池大小:" + current);
            if (client == null) {
                client = initWSClient(url);
            }
            return client;
        }

        /**
         * 将连接放回连接池
         * 
         * @param client
         */
        public void reuse(Client client) {
            if (client == null) {
                return;
            }
            synchronized (this) {
                if (current < pool.length - 1) {
                    pool[++current] = client;
                } else {
                    destoryWSClient(client);
                }
            }
        }

        /**
         * 销毁某个连接
         * 
         * @param client
         */
        public void destory(Client client) {
            if (client != null) {
                destoryWSClient(client);
            }
        }

        /**
         * 获取连接池实例
         * 
         * @param url
         * @return
         */
        public static ClientPool getInstance(String url) {
            if (StringUtils.isEmpty(url)) {
                return null;
            }
            ClientPool pool = pools.get(url);
            if (pool == null) {
                synchronized (pools) {
                    pool = pools.get(url);
                    if (pool == null) {
                        pool = new ClientPool(url,5);
                        pools.put(url,pool);
                    } else {
                        pool = pools.get(url);
                    }
                }
            }
            return pool;
        }

    }

    private WSUtil() {
        // 单例模式工具类,防止外部实例化
    }

    /**
     * 初始化webservice客户端
     * 
     * @param url
     *            wsdl地址
     */
    private static Client initWSClient(String url) {
        if (StringUtils.isBlank(url)) {
            return null;
        }
        ProxyClient client = null;
        try {
            client = new ProxyClient(new URL(url)); // 根据WSDL创建客户实例
        } catch (MalformedURLException e) {
            logger.error("生成webservice客户端出错,URL:" + url,e);
        } catch (Exception e) {
            logger.error("生成webservice客户端出错,e);
        } finally {
            if (client != null) {
                try {
                    client.reallyClose();
                } catch (Exception e) {
                    logger.error("释放webservice客户端出错,e);
                }
            }
        }
        return client;
    }

    /**
     * 释放webservice客户端
     * 
     * @param url
     */
    private static void destoryWSClient(Client client) {
        if (client != null) {
            try {
                ((ProxyClient) client).reallyClose();
            } catch (Exception e) {
                logger.error("释放webservice客户端失败,URL:" + client.getUrl());
            }
        }
    }

    /**
     * 用指定客户端执行远程调用
     * 
     * @param Client
     *            Client
     * @param invokeFunc
     *            调用方法
     * @param objArray
     *            参数
     * @return
     * @throws Exception
     */
    private static String executeRemoteCall4String(Client client,String invokeFunc,Object[] objArray) throws Exception {
        if (client == null) {
            return null;
        }
        Object[] results = client.invoke(invokeFunc,objArray);
        if (results != null && results.length > 0) {
            String resultStr = (String) results[0];
            if (logger.isDebugEnabled()) {
                logger.debug("执行webservice返回结果:" + resultStr);
            }
            return resultStr;
        }
        return null;
    }

    /**
     * 执行远程调用,单例模式调用
     * 
     * @param url
     *            wsdl URL
     * @param invokeFunc
     *            调用方法
     * @param objArray
     *            参数
     * @return
     * @throws Exception
     */
    public static String remoteCall(String url,Object... param) {
        Client client = null;
        ClientPool pool = ClientPool.getInstance(url);
        logger.info("执行webservice使用参数:" + Arrays.toString(param));
        logger.info("执行webservice调用方法:" + invokeFunc);
        try {
            client = pool.get();
            return executeRemoteCall4String(client,invokeFunc,param);
        } catch (Exception e) {
            logger.error("执行webservice调用失败,尝试重新初始化客户端后调用",e);
            pool.destory(client);
            client = pool.get();
            try {
                return executeRemoteCall4String(client,param);
            } catch (Exception e1) {
                logger.error("error ro invoke function: " + invokeFunc
                        + ",where remote call url=" + url + " and params:"
                        + Arrays.toString(param));
            }
        } finally {
            pool.reuse(client);
        }
        return null;
    }

    public static synchronized String remoteInvoke(String url,Object... param) {
        Client client = null;
        try {
            client = new Client(new URL(url));
            logger.info("执行webservice使用参数:" + Arrays.toString(param));
            logger.info("执行webservice调用方法:" + invokeFunc);
            return executeRemoteCall4String(client,param);
        } catch (MalformedURLException e) {
            logger.error("error invoke function " + invokeFunc + ",params :"
                    + Arrays.toString(param));
        } catch (Exception e) {
            logger.error("error invoke function " + invokeFunc + ",params :"
                    + Arrays.toString(param));
        } finally {
            //client.close();
        }
        return null;
    }

    /**
     * 调用webservice,并封装返回结果
     * 
     * @param url
     *            wsdl
     * @param invokeFunc
     *            执行的方法
     * @param objArray
     *            参数数组
     * @return
     */
    public static Document remoteCallForXmlDocument(String url,Object... objArray) {
        String result = remoteCall(url,objArray);
        if (result != null) {
            try {
                return DocumentHelper.parseText(result);
            } catch (DocumentException e) {
                logger.error("webservice调用返回结果不是XML格式,XML解析出错",e);
            }
        }
        return null;
    }

    /**
     * 判断远程调用是否成功
     * 
     * @param result
     * @return
     */
    public static boolean isRemoteCallSuccess(String result) {
        try {
            return isRemoteCallSuccess(DocumentHelper.parseText(result));
        } catch (DocumentException e) {
            logger.error("webservice调用返回结果不是XML格式,e);
        }
        return false;
    }

    /**
     * 判断远程调用是否成功
     * 
     * @param result
     * @return
     */
    public static boolean isRemoteCallSuccess(Document doc) {
        Element e = doc.getRootElement();
        // 如果不是<Result status='errorCode'></Result>格式的返回,则不进行校验
        if (e.element("Result") == null) {
            return true;
        }
        String status = e.attributeValue("status");
        if (WSCALL_STATUS_SUCCESS.equals(status)) {
            return true;
        }
        return false;
    }
}
在具体调用的时候使用:WSUtil.remoteCall(wsdl,"getAjList",req);//“wsdl”为调用的url,“getList”为方法名字,“req”为传递的参数(json)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读