基於soapui源碼二次開發解析WSDL


       使用過soapUI開發工具的同學都知道,根據wsdl地址可以生成基於soap1.1協議和soap1.2協議兩個版本的soap請求報文,便於開發或測試人員進行接口測試,不過遺憾的是不能對wsdl進行批量解析生成請求報文。基於此,本文在soapui源碼的基礎進行了二次開發,增加了對wsdl的批量解析。並且集成了mybatis,對mysql或oracle數據庫進行讀寫操作,便於存儲解析后的報文等信息。源碼已上傳至github,若需要請前往閱讀和下載,有幫助順便送上小星星哦!感謝!

一、需求背景

(一)soap報文格式修改:通常情況下,使用soapUI生成的請求報文標簽之間是用“?”填充的,而根據業務需求,需要將其替換成“${標簽名}”,譬如說由原來的“<xsd:bankCode>?</xsd:bankCode>"修改為“<xsd:bankCode>${bankCode}</xsd:bankCode>";其次,soapUI生成的請求報文具有一定的格式(換行、空格),所以將不必要的內容進行刪除,包括無用的注釋等信息,以免占用空間。
(二)批量解析wsdl文檔:若是業務量不多,使用soapUI生成報文,然后手動修改即可,不過現在的業務量較大,需要對幾百個wsdl進行解析,所以需要對源碼進行修改,添加和封裝來解決批量解析的問題。
(三)持久化數據庫:最后需要對解析后的報文存儲到數據庫,以便后續開發使用。
二、代碼簡介
(一)soap報文格式修改
       首先解決第一個需求,這部分可以定位到soapui源碼com.eviware.soapui.impl.wsdl.support.xsd.SampleXmlUtil工具類。分析源碼可知,其主要思想就是將wsdl文檔中的標簽元素解析出來后,在標簽之間插入“?”。因此將processElement()方法中解析出來的標簽元素element.getName().getLocalPart()聲明為全局變量myElement,然后將“?”替換成“${myElement}”即可,具體詳見我的源碼,點擊SampleXmlUtil
(二)批量解析wsdl文檔
       為了方便解析wsdl,所以在soapui源碼的基礎上二次開發,新增加了一個工具包com.founder.soapui,用來封裝和解析wsdl。

 1 package com.founder.soapui;
 2 import com.eviware.soapui.impl.wsdl.WsdlOperation;
 3 /**
 4  * @author :Mark Wang
 5  * @date :Created in 07/05/2020 10:07:06
 6  * @description: Encapsulates the necessary information of WsdlOperation
 7  * @modified By:
 8  * @version: 1.0
 9  */
10 public class OperationInfo {
11     private String operationName;
12     private String requestXml;
13     private String responseXml;
14 
15     public OperationInfo(WsdlOperation operation) {
16         operationName = operation.getName();
17         requestXml = operation.createRequest( true );
18         responseXml = operation.createResponse(true);
19     }
20 }
 1 package com.founder.soapui;
 2 import com.eviware.soapui.impl.wsdl.WsdlInterface;
 3 import com.eviware.soapui.impl.wsdl.WsdlOperation;
 4 import java.util.ArrayList;
 5 import java.util.List;
 6 /**
 7  * @author :Mark Wang
 8  * @date :Created in 07/05/2020 10:07:06
 9  * @description: Encapsulates the necessary information of WsdlInterface
10  * @modified By:
11  * @version: 1.0
12  */
13 public class InterfaceInfo {
14     private String interfaceName;
15     private List<OperationInfo> operations;
16     private String[] address;
17 
18     public InterfaceInfo(WsdlInterface wsdlInterface) {
19         this.interfaceName = wsdlInterface.getName();
20         this.address = wsdlInterface.getEndpoints();
21         int operationNum = wsdlInterface.getOperationCount();
22         List<OperationInfo> operations = new ArrayList<OperationInfo>();
23 
24         for(int i = 0; i < operationNum; i++) {
25             WsdlOperation operation = ( WsdlOperation )wsdlInterface.getOperationAt( i );
26             OperationInfo operationInfo = new OperationInfo(operation);
27             operations.add(operationInfo);
28         }
29         this.operations = operations;
30     }
31 }
 1 package com.founder.soapui;
 2 import com.eviware.soapui.impl.wsdl.WsdlInterface;
 3 import com.eviware.soapui.impl.wsdl.WsdlProject;
 4 import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlImporter;
 5 import java.util.ArrayList;
 6 import java.util.List;
 7 /**
 8  * @author :Mark Wang
 9  * @date :Created in 07/05/2020 10:07:06
10  * @description: Load information according to wsdl location
11  * @modified By:
12  * @version: 1.0
13  */
14 public class WsdlInfo {
15     private String wsdlName;
16     private List<InterfaceInfo> interfaces;
17 
18     public WsdlInfo(String path) throws Exception {
19         WsdlProject project = new WsdlProject();
20         WsdlInterface[] wsdlInterfaces = WsdlImporter.importWsdl( project, path );
21         this.wsdlName = path;
22         if(null != wsdlInterfaces)
23         {
24             List<InterfaceInfo> interfaces = new ArrayList<InterfaceInfo>();
25             for(WsdlInterface wsdlInterface : wsdlInterfaces)
26             {
27                 InterfaceInfo interfaceInfo = new InterfaceInfo(wsdlInterface);
28                 interfaces.add(interfaceInfo);
29             }
30             this.interfaces = interfaces;
31         }
32     }
33  }
 1 package com.founder.soapui;
 2 import java.util.ArrayList;
 3 import java.util.List;
 4 /**
 5  * @author :Mark Wang
 6  * @date :Created in 07/05/2020 10:07:06
 7  * @description: Batch parsing WSDL to generate request message
 8  * @modified By:
 9  * @version: 1.0
10  */
11 public class BatchWsdlParse {
12     private static List<String> soapRequest = new ArrayList<>();
13 
14     /**
15      * Parsing WSDL to get request message
16      * @param wsdlLocation
17      * @return
18      * @throws Exception
19      */
20     public static List<String> wsdlParse (String wsdlLocation) throws Exception {
21         WsdlInfo wsdlInfo = new WsdlInfo(wsdlLocation);
22         for (InterfaceInfo interfaceInfo : wsdlInfo.getInterfaces()) {
23             soapRequest.add(parseInterfaceInfo (interfaceInfo));
24         }
25         return soapRequest;
26     }
27 
28     /**
29      * Batch wsdl parse
30      * @param String
31      * @return
32      * @throws Exception
33      */
34     public static List<String> batchWsdlParse (List<String> wsdlList) throws Exception {
35         for (WsdlUrl wsdlUrl : wsdlList) {
36             WsdlInfo wsdlInfo = new WsdlInfo(wsdlUrl);
37             for (InterfaceInfo interfaceInfo : wsdlInfo.getInterfaces()) {
38                 soapRequest.add(parseInterfaceInfo (interfaceInfo));
39             }
40         }
41         return soapRequest;
42     }
43 
44     /**
45      * parse InterfaceInfo
46      * @param interfaceInfo
47      * @param serviceId
48      * @return
49      */
50     public static String parseInterfaceInfo (InterfaceInfo interfaceInfo) {
51         return interfaceInfo.getOperations().get(0).getRequestXml();
52     }
53 }
 1 /**
 2  * @author :Mark Wang
 3  * @date :Created in 07/05/2020 10:07:06
 4  * @description: Test to parse wsdl
 5  * @modified By:
 6  * @version: 1.0
 7  */
 8 public class WSDLParseTest {
 9     private String wsdlLocation = "http://192.168.1.18:8001/CHNAppxServices/services/XfaceSellingTransactionWrapper?wsdl";
10     
11     @Test
12     public void wsdlParseTest () throws Exception {
13         List<String> requestList = BatchWsdlParse.wsdlParse(wsdlLocation);
14         for (String request : requestList) {
15             System.out.println(request);
16         }
17     }
18 
19     @Test
20     public void batchWsdlParseTest() throws Exception {
21         List<String> wsdlList = new ArrayList<>();
22         wsdlList.add(wsdlLocation);
23         List<String> requestList = BatchWsdlParse.batchWsdlParse(wsdlList);
24         for (String request : requestList) {
25             System.out.println(request);
26         }
27     }
28 }

 

(三)持久化數據庫
       根據以上代碼足以完成對wsdl的批量解析(get和set方法省略),至於將解析后必要的信息持久化數據庫,主要是集成了mybatis,若是需要可以參考我的源碼,這里就不啰嗦了!
三、個人總結
       其實研究過soapui源碼的同學肯定知道,其實它也是基於wsdl4j,所以我們完全可以用wsdl4j對wsdl進行解析。之所以研究soapui源碼,主要是為了學習學習!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM