根据WebService地址展示方法列表、入参和返回值(解析wsdl)

更多详细请看我的博客:xuchuruo.cn

项目源码:https://gitee.com/xuchuruo/parsing_wsdl(有些jar包Maven上无法下载)

----------------------------------------------------------------

主要使用XPATH来解析wsdl文档,dom4j解析xsd

建议先了解一下WSDL的一些元素所代表的含义

效果(返回值暂时没做,逻辑是一样的):

根据WebService地址展示方法列表、入参和返回值(解析wsdl)_第1张图片

 

获取Document方法:

 

/**
     * 得到wsdl文件的根结点的document
     *
     * @param wsdlUrl
     * @return
     * @throws Exception
     */
    public static Document getDefinitionDocument(String wsdlUrl) throws Exception {
        Definition def = getDefinition(wsdlUrl);

        WSDLWriter writer = getWsdlFactory().newWSDLWriter();
        Document document = writer.getDocument(def);

        return document;
    }

 

 

 

获取Xpath方法:

 

   /**
     * 得到document的查找工具xpath
     *
     * @param document
     * @return
     * @throws Exception
     */
    public static XPath getXpath(Document document) throws Exception {
        XPath xpath = XPathFactory.newInstance().newXPath();
        xpath.setNamespaceContext(new UniversalNamespaceCache(document, false));
        return xpath;
    }

 

 

 

Controller层:

 

/**
 * @author: 徐楚若
 * @date: 2018/1/22 14:01
 */

@RestController
@RequestMapping("webserviceForm")
public class CustomForm {

    /**
     * 获取指定webservice的所有方法
     *
     * @param webserviceUrl
     * @return
     * @throws Exception
     */
    @RequestMapping("findMethods")
    public List getAllMethod(Model model, String webserviceUrl) throws Exception {
        // 如果接收的URL为空,返回
        if (webserviceUrl == null) {
            return null;
        }
        List list = new BmWsTestBoImpl().getAllMethodByServiceUrl(webserviceUrl);
        model.addAttribute("methodList", list);
        return list;
    }

    /**
     * 根据方法名称和webserviceUrl得到入参和类型
     *
     * @param methodName
     * @param webserviceUrl
     * @return
     * @throws Exception
     */
    @RequestMapping("getParamByMethodNameAndWsUrl")
    public List getParamByMethodNameAndWsUrl(String methodName, String webserviceUrl,Model model) throws Exception {
        List list = new BmWsTestBoImpl().getParamByMethodNameAndWsUrl(methodName, webserviceUrl);
        model.addAttribute("paramList",list);
        return list;
    }

}


Service实现类(工具方法较多)

 

 

 @Override
    public List getAllMethodByServiceUrl(String webserviceUrl) throws Exception {
        // 结果
        List list = new ArrayList();
        try {
            // 将url修正为合法的url,即带wsdl后缀的
            webserviceUrl = getWebserviceUrl(webserviceUrl);
            if (StringUtils.isNotEmpty(webserviceUrl)) {
                List methodList = WsdlUtil.getOperationList(webserviceUrl);
                for (String methodName : methodList) {
                    WebServiceMethod webServiceMethod = new WebServiceMethod();
                    webServiceMethod.setName(methodName);

                    list.add(webServiceMethod);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
        return list;
    }

 

/**
     * 将webserviceUrl路径转为合法的路径
     *
     * @param webserviceUrl
     * @return
     * @throws Exception
     */
    public String getWebserviceUrl(String webserviceUrl) {
        if (StringUtils.isNotEmpty(webserviceUrl)) {
            // 判断url里面是否存在wsdl后缀
            if (webserviceUrl.indexOf("?") >= 0) {
                if (!webserviceUrl.endsWith("wsdl")) {
                    webserviceUrl = new StringBuilder(webserviceUrl).append("wsdl").toString();
                }
            } else {
                webserviceUrl = new StringBuilder(webserviceUrl).append("?wsdl").toString();
            }
            return webserviceUrl;
        } else {
            return "";
        }
    }
/**
     * 得到wsdl中所有的方法
     *
     * @param wsdlUrl
     * @return
     * @throws Exception
     */
    public static List getOperationList(String wsdlUrl) throws Exception {
        Document document = getDefinitionDocument(wsdlUrl);

        NodeList operations = DOMUtil.findNodeList(document, "wsdl:definitions/wsdl:portType/wsdl:operation");

        // 返回的结果集list
        List operationList = new ArrayList();
        for (int i = 0; i < operations.getLength(); i++) {
            Node operation = operations.item(i);
            String operationName = DOMUtil.getNodeName(operation);
            if (operationName != null && !"".equals(operationName)) {
                operationList.add(operationName);
            }
        }
        return operationList;
    }
 /**
     * 在document中查找结点
     *
     * @param document
     * @param xpathStr
     * @return
     * @throws Exception
     */
    public static NodeList findNodeList(Document document, String xpathStr) throws Exception {
        XPath xpath = WsdlUtil.getXpath(document);
        NodeList nodeList = (NodeList) xpath.evaluate(xpathStr, document, XPathConstants.NODESET);
        return nodeList;
    }
    /**
     * 得到结点的属性值
     *
     * @param node
     * @param attributeName
     * @return
     * @throws Exception
     */
    public static String getAttributeValue(Node node, String attributeName) throws Exception {
        String attributeValue = "";
        if (node != null) {
            NamedNodeMap attributeMap = node.getAttributes();
            Node attributeNode = attributeMap.getNamedItem(attributeName);
            if (attributeNode != null) {
                attributeValue = attributeNode.getNodeValue();
            }
        }
        return attributeValue;
    }

    /**
     * 得到结点的name属性值
     *
     * @param node
     * @return
     * @throws Exception
     */
    public static String getNodeName(Node node) throws Exception {
        return getAttributeValue(node, "name");
    }

获取入参和类型:

 

/**
     * 根据方法名称和webserviceUrl得到参数
     *
     * @param methodName
     * @param webserviceUrl
     * @return
     * @throws Exception
     */
    @Override
    public List getParamByMethodNameAndWsUrl(String methodName, String webserviceUrl) throws Exception {
        try {
            // 将url修正为合法的url,即带wsdl后缀的
            webserviceUrl = getWebserviceUrl(webserviceUrl);
            Document document = WsdlUtil.getDefinitionDocument(webserviceUrl);
            XPath xpath = WsdlUtil.getXpath(document);
            // 查找import元素
            NodeList nodeList = (NodeList) xpath.evaluate("/wsdl:definitions/wsdl:types/xsd:schema/xsd:import", document, XPathConstants.NODESET);
            // 获取指定名称的值
            Node schemaLocationNode = nodeList.item(0).getAttributes().getNamedItem("schemaLocation");
            // 读取xsd
            String xsdURL = schemaLocationNode.getNodeValue();
            SAXReader saxReader = new SAXReader();
            org.dom4j.Document dom4j_Document = saxReader.read(xsdURL);
            // 查找指定方法名称的元素
            Element element = (Element) dom4j_Document.selectSingleNode("//xs:element[@name='" + methodName + "']");
            // 获取数据
            List list = new ArrayList();
            List parameterInfo = treeWalk(element, list);
            return parameterInfo;
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取所有元素名称
     */
    public static List treeWalk(Element element, List list) {
        // 获取根元素下的所有子元素
        List es = element.elements();
        for (Element e : es) {
            if (e.attribute("name") != null) {
                // 封装数据
                ParameterInfo parameterInfo = new ParameterInfo();
                // 入参
                Attribute name = e.attribute("name");
                parameterInfo.setName(name.getValue());
                // 方法类型
                Attribute type = e.attribute("type");
                parameterInfo.setType(type.getValue().split(":")[1]);
                list.add(parameterInfo);
                treeWalk(e, list);
            } else {
                treeWalk(e, list);
            }
        }
        return list;
    }


代码需要根据wsdl结构来修改xpath的查询语法

 

代码中

NodeList operations = DOMUtil.findNodeList(document, "wsdl:definitions/wsdl:portType/wsdl:operation");

 

表示的意义即为从根节点wsdl:definitions层层往下找到子节点,再用AIP获取到方法名

 

可能wsdl结构会有不同,方法的入参和返回值没在wsdl里,所以要去xsd文档里取

直接取import里的第一个值即为方法参数.....(自己根据wsdl结构去查看方法在哪个xsd)

 

// 查找import元素
NodeList nodeList = (NodeList) xpath.evaluate("/wsdl:definitions/wsdl:types/xsd:schema/xsd:import", document, XPathConstants.NODESET);

 

根据WebService地址展示方法列表、入参和返回值(解析wsdl)_第2张图片

 

 

// 查找指定方法名称的元素
Element element = (Element) dom4j_Document.selectSingleNode("//xs:element[@name='" + methodName + "']");

 

这里直接使用[//]来定位到元素位置,视情况使用,如果你的文件里有多个相同的,还需要判断

//title[@*] 选取所有带有属性的 title 元素。 

根据WebService地址展示方法列表、入参和返回值(解析wsdl)_第3张图片

 

 

 

到这里就完成了~

有一点需要注意的是,如果你跟我一样也要解析xsd才能获取到入参和类型

xsd我不是用的XPATH,是用的dom4j,在用它的API的时候,必须要添加外部的一个jar包,不然会报错.

 



    jaxen
    jaxen
    1.1.1

 

如果对表达式不清楚的可以看:

XPath用法及代码样例

你可能感兴趣的:(XPath解析文档)