webService 发送soap请求,并解析返回的soap报文

本例应用场景:要做一个webService测试功能,不局限于任何一种固定格式的webService,所以像axis,cxf等框架就不好用了。只有深入到webService的原理,通过发收soap报文,来调用服务返回结果。

发送请求:

 /**
     * 通过httpClient发送soap报文
     * @param requestSoap 请求报文
     * @param serviceAddress 请求地址
     * @param charSet 字符集
     * @param contentType 返回的contentType
     * @return 响应报文
     * @throws WebServiceModuleRuntimeException
     */
    public String sendRequestSoap(String requestSoap, String serviceAddress, String charSet, String contentType)
            throws WebServiceModuleRuntimeException {
        String resultSoap = "";
        PostMethod postMethod = new PostMethod(serviceAddress);
        byte[] b = new byte[0];
        try {
            b = requestSoap.getBytes(charSet);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        InputStream is = new ByteArrayInputStream(b, 0, b.length);
        RequestEntity re = new InputStreamRequestEntity(is, b.length, contentType);
        postMethod.setRequestEntity(re);

        HttpClient httpClient = new HttpClient();
        int statusCode = 0;
        try {
            statusCode = httpClient.executeMethod(postMethod);
            System.out.println("statusCode = " + statusCode);
        } catch (IOException e) {
            throw new WebServiceModuleRuntimeException("执行http请求失败", e);
        }
        if (statusCode == 200) {
            try {
                resultSoap = postMethod.getResponseBodyAsString();
            } catch (IOException e) {
                throw new WebServiceModuleRuntimeException("获取请求返回报文失败", e);
            }
        } else {
            throw new WebServiceModuleRuntimeException("请求失败:" + statusCode);
        }

        return resultSoap;
    }
//调用请求方法,发送报文
String responseSoap = "";
        try{
            responseSoap = webServiceService.sendRequestSoap(requestSoap,struct.getWebAddress(),"utf-8","text/xml; charset=utf-8");
        }catch (WebServiceModuleRuntimeException ex){
            throw new ModuleException("发动请求失败",ex);
        }

解析返回报文:

因没有固定格式,所以无法通过jaxb工具来xml转bean,更没有客户端代码可以用。所以只有解析返回报文中,可以标识返回结果的值,比如成功、success、ok等。

此处考虑两种情况:第一种状态码放在标签的属性值中,第二种状态作为标签的内容:

<result ResultCode="0" ResultCodeDesc="成功">
<result_code>0</result_code>
System.out.println(parseResponseSoap("result_code", "", responseSoap));

/**
     * 解析返回报文
     * @param node 标记所在节点
     * @param attr 标记所在属性
     * @param soap 报文
     * @return 标记值
     * @throws WebServiceModuleRuntimeException
     */
    public static String parseResponseSoap(String node, String attr, String soap) throws WebServiceModuleRuntimeException {
        //然后用SOAPMessage 和 SOAPBody
        Document personDoc;
        try {
            personDoc = new SAXReader().read(new StringReader(soap));
            Element rootElt = personDoc.getRootElement(); // 获取根节点
            Iterator body = rootElt.elementIterator("Body");
            while (body.hasNext()) {
                Element recordEless = (Element) body.next();
                return nextSubElement(node,attr,recordEless);
            }
        } catch (DocumentException e) {
            throw new WebServiceModuleRuntimeException("解析返回报文失败", e);
        }
        return "";
    }
/**
     * 递归方法,查找本节点是否有标记信息,如果没有就查找下一层,
     * 在下一层里同样查找本层节点,只要找到值,就层层返回。
     * @param node 节点标签名
     * @param attr 节点属性值
     * @param el 当前节点对象
     * @return 目标值
     */
    public static String nextSubElement(String node, String attr, Element el) {
        if (el.getName().equals(node)) {
            //说明 找到了目标节点
            //属性值为空说明取标签内容
            if (attr.equals("")) {
                Iterator sub2 = el.elementIterator();
                //有子节点说明标签内容不是单一值,需要拿到查询结果
                if (sub2.hasNext()) {
                    while (sub2.hasNext()) {
                        Element s2 = (Element) sub2.next();
                        //如果返回的不是单一的标记值,而是查询结果,有些麻烦,
                        //查询结果应当是list<map>格式,但是map的key值不好确定,是标签名作为key还是属性值作为key
                        //todo
                    }
                } else {
                    return  el.getText();
                }

            } else {
                Attribute attrbute = el.attribute(attr);
                return attrbute.getText();
            }
        } else {
            Iterator sub2 = el.elementIterator();
            while (sub2.hasNext()) {
                Element sub = (Element) sub2.next();
                return nextSubElement(node, attr, sub);
            }
        }
        return "";
    }

后记:本篇代码满足我自己的需求,但是看官的需求各异,本篇仅提供部分参考。

原文地址:https://www.cnblogs.com/opensesame/p/6018403.html