webservie客户端, 调用以及解析xml

Ai糖宝 2020年05月28日 63次浏览

天气webservie客户端, 调用以及解析xml

工具类HttpClientCallSoapUtil, 请求webservice


import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicHeader;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;
import org.apache.xmlbeans.impl.util.Base64;
import org.springframework.util.StringUtils;

import java.nio.charset.Charset;
import java.util.List;
import java.util.Map;

public class HttpClientCallSoapUtil {

    static int socketTimeout = 30000;// 请求超时时间
    static int connectTimeout = 30000;// 传输超时时间
    static Logger logger = Logger.getLogger(HttpClientCallSoapUtil.class);

    /**
     * 使用SOAP1.1发送消息
     *1.1 可以请求 1.1 和1.2
     * @param postUrl
     * @param soapXml
     * @param soapAction
     * @return
     */
    public static String doPostSoap1_1(String postUrl, String soapXml,
                                       String soapAction,String userpass) {
        String retStr = "";
        // 创建HttpClientBuilder
        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
        // HttpClient
        CloseableHttpClient closeableHttpClient = httpClientBuilder.build();
        HttpPost httpPost = new HttpPost(postUrl);
        //  设置请求和传输超时时间
        RequestConfig requestConfig = RequestConfig.custom()
                .setSocketTimeout(socketTimeout)
                .setConnectTimeout(connectTimeout).build();
        httpPost.setConfig(requestConfig);
        try {
            httpPost.setHeader("Content-Type", "text/xml;charset=utf-8");
            httpPost.setHeader("SOAPAction", soapAction);
            //用户验证
            if(!StringUtils.isEmpty(userpass)){
                httpPost.setHeader(new BasicHeader("Authorization","Basic " + Base64.encode(userpass.getBytes())));
            }
            StringEntity data = new StringEntity(soapXml,
                    Charset.forName("utf-8"));
            httpPost.setEntity(data);
            CloseableHttpResponse response = closeableHttpClient
                    .execute(httpPost);
            HttpEntity httpEntity = response.getEntity();
            if (httpEntity != null) {
                // 打印响应内容
                retStr = EntityUtils.toString(httpEntity, "UTF-8");
                logger.info("response:" + retStr);
            }
            // 释放资源
            closeableHttpClient.close();
        } catch (Exception e) {
            logger.error("exception in doPostSoap1_1", e);
        }
        return retStr;
    }


    /**
     * 使用SOAP1.2发送消息
     *只能请求1.2
     * @param postUrl
     * @param soapXml
     * @param soapAction
     * @return
     */
    public static String doPostSoap1_2(String postUrl, String soapXml,
                                       String soapAction) {
        String retStr = "";
        // 创建HttpClientBuilder
        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
        // HttpClient
        CloseableHttpClient closeableHttpClient = httpClientBuilder.build();
        HttpPost httpPost = new HttpPost(postUrl);
        // 设置请求和传输超时时间
        RequestConfig requestConfig = RequestConfig.custom()
                .setSocketTimeout(socketTimeout)
                .setConnectTimeout(connectTimeout).build();
        httpPost.setConfig(requestConfig);
        try {
            httpPost.setHeader("Content-Type",
                    "application/soap+xml;charset=UTF-8");
            httpPost.setHeader("SOAPAction", soapAction);
            StringEntity data = new StringEntity(soapXml,
                    Charset.forName("UTF-8"));
            httpPost.setEntity(data);
            CloseableHttpResponse response = closeableHttpClient
                    .execute(httpPost);
            HttpEntity httpEntity = response.getEntity();
            if (httpEntity != null) {
                // 打印响应内容
                retStr = EntityUtils.toString(httpEntity, "utf-8");
                logger.info("response:" + retStr);
            }
            // 释放资源
            closeableHttpClient.close();
        } catch (Exception e) {
            logger.error("exception in doPostSoap1_2", e);
        }
        return retStr;
    }


}

解析xml

import java.util.*;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Namespace;
import org.dom4j.QName;

/**
 * Dom4j工具类
* @ClassName: Dom4jUtil 
* @Description: TODO(这里用一句话描述这个类的作用) 
* @author wwm
* @date 2019年3月19日 下午18:41:52
 */
public class Dom4jUtil
{
	/**
	 * Xml转Map类型方法【通用方式】
	* @Title: ele2Map 
	* @param @param xml
	* @param @return 参数
	* @return Map<String,Object> 返回类型
	 */
	@SuppressWarnings("unchecked")
	public static Map Xml2Map(String xml) throws Exception
	{
		Map rtnMap = new HashMap<String, Object>();
		Document document = DocumentHelper.parseText(xml);
		Element root = document.getRootElement();
		
		rtnMap = (Map<String, Object>) ele2Map(root);
		return rtnMap;
	}
	
	@SuppressWarnings("unchecked")
	public static Object ele2Map(Element element)
	{
		Map<String, Object> map = new HashMap<String, Object>();
		List<Element> elements = element.elements();
		if (elements.size() == 0)
		{
			map.put(element.getName(), element.getText());
			if (!element.isRootElement())
			{
				return element.getText();
			}
		} else if (elements.size() == 1)
		{
			map.put(elements.get(0).getName(), ele2Map(elements.get(0)));
		} else if (elements.size() > 1)
		{
			// 多个子节点的话就得考虑list的情况了,比如多个子节点有节点名称相同的
			// 构造一个map用来去重
			Map<String, Element> tempMap = new HashMap<String, Element>();
			for (Element ele : elements)
			{
				tempMap.put(ele.getName(), ele);
			}
			Set<String> keySet = tempMap.keySet();
			for (String string : keySet)
			{
				Namespace namespace = tempMap.get(string).getNamespace();
				List<Element> elements2 = element.elements(new QName(string, namespace));
				// 如果同名的数目大于1则表示要构建list
				if (elements2.size() > 1)
				{
					List<Object> list = new ArrayList<Object>();
					for (Element ele : elements2)
					{
						list.add(ele2Map(ele));
					}
					map.put(string, list);
				} else
				{
					// 同名的数量不大于1则直接递归去
					map.put(string, ele2Map(elements2.get(0)));
				}
			}
		}

		return map;
	}


	/**
	 * xml转list
	 * @param xml
	 * @return
	 * @throws Exception
	 */
	public static List xmlToList(String xml) throws Exception{
		Map map = Xml2Map(xml);
		return mapToList(map);
	}


	/**
	 * xml转list
	 * @param xml
	 * @return
	 * @throws Exception
	 */
	public static List mapToList(Map map) throws Exception{
		List list = new ArrayList();
		// 获得map的Iterator
		Iterator iter = map.entrySet().iterator();
		while (iter.hasNext()) {
			Map.Entry entry = (Map.Entry) iter.next();
			list.add(entry.getValue());
		}
		return list;
	}

}

实践, 如果写的不好, 请指明

    public static void main(String[] args) throws Exception{
        String xmlStr = doPostSoap1_1("http://www.webxml.com.cn/WebServices/WeatherWebService.asmx",formatSOAPRequest("山东"),"http://WebXml.com.cn/getSupportCity",null);
        Map map = Dom4jUtil.Xml2Map(xmlStr);

        List<String> list = (List)((Map)((Map)((Map)map.get("Body")).get("getSupportCityResponse")).get("getSupportCityResult")).get("string");
    }
    
    
        /**
     * 参数请求组装
     * @param byProvinceName
     * @return
     */
    private static String formatSOAPRequest(String byProvinceName) {
        StringBuffer sb = new StringBuffer();
        sb.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
        sb.append("<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">");
        sb.append("  <soap:Body>");
        sb.append("    <getSupportCity xmlns=\"http://WebXml.com.cn/\">");
        sb.append("      <byProvinceName>"+byProvinceName+"</byProvinceName>");
        sb.append("    </getSupportCity>");
        sb.append("  </soap:Body>");
        sb.append("</soap:Envelope>");
        return sb.toString();

    }

转实体:

因为天气的官方返回一层一层的, 所以获取的时候, 麻烦了一些, 如果返回值是如下, 便可直接转为实体, xml转map, map转list实体

public static void main(String[] args) throws Exception{
        String xmlStr1 = doPostSoap1_1("http://www.webxml.com.cn/WebServices/WeatherWebService.asmx",formatSOAPRequest("山东"),"http://WebXml.com.cn/getSupportCity",null);
//        System.out.println("xmlStr::::"+xmlStr);
        String xmlStr = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n" +
                "<getUser>\n" +
                "    <test0>\n" +
                "        <employeeID>1E9B0F93-C7CB-4555-AAD5-0D105963FF4A</employeeID>\n" +
                "        <employeeCode>0004351</employeeCode>\n" +
                "        <employeeName>张三</employeeName>\n" 
                "    </test0>\n" +
                "    <test1>\n" +
                "        <employeeID>CB7BDC66-F01B-479E-B1A6-11F1E101248C</employeeID>\n" +
                "        <employeeCode>0004352</employeeCode>\n" +
                "        <employeeName>李四</employeeName>\n" +
                "    </test1>\n" +
                "</getUser>";
        List<UserResp> list = Dom4jUtil.xmlToList(xmlStr);
        System.out.println(list);
    }