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

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

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

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

获取Document

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/** 
* 得到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

1
2
3
4
5
6
7
8
9
10
11
12
/** 
* 得到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层

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
/** 
* @author: 徐楚若
* @date: 2018/1/22 14:01
*/

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

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

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

}

Service实现类

  • 工具方法较多
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Override  
public List<WebServiceMethod> getAllMethodByServiceUrl(String webserviceUrl) throws Exception {
// 结果
List<WebServiceMethod> list = new ArrayList<WebServiceMethod>();
try {
// 将url修正为合法的url,即带wsdl后缀的
webserviceUrl = getWebserviceUrl(webserviceUrl);
if (StringUtils.isNotEmpty(webserviceUrl)) {
List<String> 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;
}

路径处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/** 
* 将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所有方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/** 
* 得到wsdl中所有的方法
*
* @param wsdlUrl
* @return
* @throws Exception
*/
public static List<String> getOperationList(String wsdlUrl) throws Exception {
Document document = getDefinitionDocument(wsdlUrl);

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

// 返回的结果集list
List<String> operationList = new ArrayList<String>();
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;
}

查找节点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
/** 
* 在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;
}
````


## 获取节点属性

```` java
/**
* 得到结点的属性值
*
* @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");
}

获取入参和类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
/** 
* 根据方法名称和webserviceUrl得到参数
*
* @param methodName
* @param webserviceUrl
* @return
* @throws Exception
*/
@Override
public List<ParameterInfo> 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<ParameterInfo> list = new ArrayList<ParameterInfo>();
List<ParameterInfo> parameterInfo = treeWalk(element, list);
return parameterInfo;
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}

/**
* 获取所有元素名称
*/
public static List<ParameterInfo> treeWalk(Element element, List<ParameterInfo> list) {
// 获取根元素下的所有子元素
List<Element> 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的查询语法

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

表示从根节点wsdl:definitions层层往下找到子节点,再用API获取到方法名

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

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

1
2
// 查找import元素
NodeList nodeList = (NodeList) xpath.evaluate("/wsdl:definitions/wsdl:types/xsd:schema/xsd:import", document, XPathConstants.NODESET);
1
2
// 查找指定方法名称的元素
Element element = (Element) dom4j_Document.selectSingleNode("//xs:element[@name='" + methodName + "']");

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

到这里就完成了~

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

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

1
2
3
4
5
6
<!-- https://mvnrepository.com/artifact/jaxen/jaxen -->
<dependency>
<groupId>jaxen</groupId>
<artifactId>jaxen</artifactId>
<version>1.1.1</version>
</dependency>

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

XPath用法及代码样例

项目git地址:https://gitee.com/xuchuruo/parsing_wsdl

------本文结束感谢阅读------

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

文章作者:churuo

原始链接:https://www.xuchuruo.cn/根据WebService地址展示方法列表、入参和返回值-解析wsdl.html

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

0%