根據WebService地址展示方法列表、入參和返回值(解析wsdl)
阿新 • • 發佈:2019-01-27
主要使用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<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實現類(工具方法較多)
@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;
}
/**
* 將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<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;
}
/**
* 在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<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的查詢語法
程式碼中
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包,不然會報錯.
<!-- https://mvnrepository.com/artifact/jaxen/jaxen --> <dependency> <groupId>jaxen</groupId> <artifactId>jaxen</artifactId> <version>1.1.1</version> </dependency>
如果對錶達式不清楚的可以看: