更多详细请看我的博客:xuchuruo.cn
项目源码:https://gitee.com/xuchuruo/parsing_wsdl(有些jar包Maven上无法下载)
----------------------------------------------------------------
主要使用XPATH来解析wsdl文档,dom4j解析xsd
建议先了解一下WSDL的一些元素所代表的含义
效果(返回值暂时没做,逻辑是一样的):
获取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);
// 查找指定方法名称的元素
Element element = (Element) dom4j_Document.selectSingleNode("//xs:element[@name='" + methodName + "']");
这里直接使用[//]来定位到元素位置,视情况使用,如果你的文件里有多个相同的,还需要判断
//title[@*] | 选取所有带有属性的 title 元素。 |
到这里就完成了~
有一点需要注意的是,如果你跟我一样也要解析xsd才能获取到入参和类型
xsd我不是用的XPATH,是用的dom4j,在用它的API的时候,必须要添加外部的一个jar包,不然会报错.
jaxen
jaxen
1.1.1
如果对表达式不清楚的可以看:
XPath用法及代码样例