基于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。

package com.founder.soapui;
import com.eviware.soapui.impl.wsdl.WsdlOperation;
/**
 * @author :Mark Wang
 * @date :Created in 07/05/2020 10:07:06
 * @description: Encapsulates the necessary information of WsdlOperation
 * @modified By:
 * @version: 1.0
 */
public class OperationInfo {
    private String operationName;
    private String requestXml;
    private String responseXml;

    public OperationInfo(WsdlOperation operation) {
        operationName = operation.getName();
        requestXml = operation.createRequest( true );
        responseXml = operation.createResponse(true);
    }
}
package com.founder.soapui;
import com.eviware.soapui.impl.wsdl.WsdlInterface;
import com.eviware.soapui.impl.wsdl.WsdlOperation;
import java.util.ArrayList;
import java.util.List;
/**
 * @author :Mark Wang
 * @date :Created in 07/05/2020 10:07:06
 * @description: Encapsulates the necessary information of WsdlInterface
 * @modified By:
 * @version: 1.0
 */
public class InterfaceInfo {
    private String interfaceName;
    private List<OperationInfo> operations;
    private String[] address;

    public InterfaceInfo(WsdlInterface wsdlInterface) {
        this.interfaceName = wsdlInterface.getName();
        this.address = wsdlInterface.getEndpoints();
        int operationNum = wsdlInterface.getOperationCount();
        List<OperationInfo> operations = new ArrayList<OperationInfo>();

        for(int i = 0; i < operationNum; i++) {
            WsdlOperation operation = ( WsdlOperation )wsdlInterface.getOperationAt( i );
            OperationInfo operationInfo = new OperationInfo(operation);
            operations.add(operationInfo);
        }
        this.operations = operations;
    }
}
package com.founder.soapui;
import com.eviware.soapui.impl.wsdl.WsdlInterface;
import com.eviware.soapui.impl.wsdl.WsdlProject;
import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlImporter;
import java.util.ArrayList;
import java.util.List;
/**
 * @author :Mark Wang
 * @date :Created in 07/05/2020 10:07:06
 * @description: Load information according to wsdl location
 * @modified By:
 * @version: 1.0
 */
public class WsdlInfo {
    private String wsdlName;
    private List<InterfaceInfo> interfaces;

    public WsdlInfo(String path) throws Exception {
        WsdlProject project = new WsdlProject();
        WsdlInterface[] wsdlInterfaces = WsdlImporter.importWsdl( project, path );
        this.wsdlName = path;
        if(null != wsdlInterfaces)
        {
            List<InterfaceInfo> interfaces = new ArrayList<InterfaceInfo>();
            for(WsdlInterface wsdlInterface : wsdlInterfaces)
            {
                InterfaceInfo interfaceInfo = new InterfaceInfo(wsdlInterface);
                interfaces.add(interfaceInfo);
            }
            this.interfaces = interfaces;
        }
    }
 }
package com.founder.soapui;
import java.util.ArrayList;
import java.util.List;
/**
 * @author :Mark Wang
 * @date :Created in 07/05/2020 10:07:06
 * @description: Batch parsing WSDL to generate request message
 * @modified By:
 * @version: 1.0
 */
public class BatchWsdlParse {
	private static List<String> soapRequest = new ArrayList<>();

	/**
     * Parsing WSDL to get request message
     * @param wsdlLocation
     * @return
     * @throws Exception
     */
	public static List<String> wsdlParse (String wsdlLocation) throws Exception {
        WsdlInfo wsdlInfo = new WsdlInfo(wsdlLocation);
        for (InterfaceInfo interfaceInfo : wsdlInfo.getInterfaces()) {
            soapRequest.add(parseInterfaceInfo (interfaceInfo));
        }
        return soapRequest;
    }

	/**
     * Batch wsdl parse
     * @param String
     * @return
     * @throws Exception
     */
    public static List<String> batchWsdlParse (List<String> wsdlList) throws Exception {
        for (WsdlUrl wsdlUrl : wsdlList) {
            WsdlInfo wsdlInfo = new WsdlInfo(wsdlUrl);
            for (InterfaceInfo interfaceInfo : wsdlInfo.getInterfaces()) {
                soapRequest.add(parseInterfaceInfo (interfaceInfo));
            }
        }
        return soapRequest;
    }

	/**
     * parse InterfaceInfo
     * @param interfaceInfo
     * @param serviceId
     * @return
     */
    public static String parseInterfaceInfo (InterfaceInfo interfaceInfo) {
		return interfaceInfo.getOperations().get(0).getRequestXml();
	}

}
/**
 * @author :Mark Wang
 * @date :Created in 07/05/2020 10:07:06
 * @description: Test to parse wsdl
 * @modified By:
 * @version: 1.0
 */
public class WSDLParseTest {
	private String wsdlLocation = "http://192.168.1.18:8001/CHNAppxServices/services/XfaceSellingTransactionWrapper?wsdl";
	
	@Test
    public void wsdlParseTest () throws Exception {
        List<String> requestList = BatchWsdlParse.wsdlParse(wsdlLocation);
        for (String request : requestList) {
            System.out.println(request);
        }
    }

	@Test
    public void batchWsdlParseTest() throws Exception {
    	List<String> wsdlList = new ArrayList<>();
    	wsdlList.add(wsdlLocation);
        List<String> requestList = BatchWsdlParse.batchWsdlParse(wsdlList);
        for (String request : requestList) {
            System.out.println(request);
        }
    }
}
      (三) 持久化数据库

       根据以上代码足以完成对wsdl的批量解析(get和set方法省略),至于将解析后必要的信息持久化数据库,主要是集成了mybatis,若是需要可以参考我的源码,这里就不啰嗦了!

三、个人总结

       其实研究过soapui源码的同学肯定知道,其实它也是基于wsdl4j,所以我们完全可以用wsdl4j对wsdl进行解析。之所以研究soapui源码,主要是为了学习学习!

原创文章 3 获赞 1 访问量 294

猜你喜欢

转载自blog.csdn.net/mark_blogs/article/details/106028083
今日推荐