WSDL文件复杂类型的解析及其实例化代码生成

1.设计要求

根据WebService的地址,对其WSDL文件进行解析,重点解析其中包含的复杂类型。针对解析出的复杂类型的结构,生成对应的类实例化代码。

2.WSDL解析过程

WSDL的解析过程就是对WSDL内标签一层一层深入的过程,直到获得所需的那一层数据,下面以WSDL文件中的复杂类型(ComplexType)的解析为例,对该部分的代码进行说明。

public void parseWSDL(String wsdlURI) throws WSDLException {
    WSDLFactory wsdlFactory = WSDLFactory.newInstance();
        WSDLReader reader = wsdlFactory.newWSDLReader();
        Definition defintion = reader.readWSDL(wsdlURI);//如图3,根据wsdlURI地址得到的definition即为最外层的标签
    processTypes(defintion);//如图4,processTypes函数对defintion下的types标签进行进一步解析
    }
}

WSDL文件复杂类型的解析及其实例化代码生成_第1张图片
图 3 WSDL文件层次_definiton
这里写图片描述
图 4 WSDL文件层次_types

public void processTypes(Definition defintion) {
    XmlSchemaCollection xmlSchemaCollection = new XmlSchemaCollection();
    Types types = defintion.getTypes();//得到definition下一级中的types
    List list = types.getExtensibilityElements();
    for (Iterator iterator = list.iterator(); iterator.hasNext(); ) {
        SchemaImpl schemaImpl = (SchemaImpl) iterator.next();
        Element element = (Element) schemaImpl.getElement();
        XmlSchema xmlSchema = xmlSchemaCollection.read(element);

        XmlSchemaObjectTable smlSchemaObjectTable = xmlSchema.getSchemaTypes();
        //如图5,得到types下的complexType
        XmlSchemaObjectTable elements = xmlSchema.getElements();
        //如图5,得到types下的element

        Iterator elementsItr=elements.getValues();//对element进行进一步深入
        while(elementsItr.hasNext()){
            XmlSchemaElement elemt = (XmlSchemaElement) elementsItr.next();
            String elemtName = elemt.getName();
            if(elemtName.equals(CodeGenerate.getBox_function())){
                XmlSchemaType elemtNameType=elemt.getSchemaType();
                search (elemtNameType); //search函数用于对复杂类型进行专门的处理
            }
        }
        Iterator typesItr = smlSchemaObjectTable.getValues();//对complexType进行进一步深入
        while (typesItr.hasNext()) {
            XmlSchemaType type = (XmlSchemaType) typesItr.next();
            String typeName = type.getName();
            if(typeName.equals(complex_type)){
                search(type);
            }
        }
    }
}

WSDL文件复杂类型的解析及其实例化代码生成_第2张图片
图 5 WSDL层次_element and complexType
由于复杂类型的处理比较麻烦,而且复杂类型中可能嵌套了复杂类型,所以单独写一个Search函数对WSDL中的复杂类型进行解析处理,由于嵌套关系的存在,代码中Search函数中利用了对Search的递归调用。

public void search(XmlSchemaType type) {
    //如果是复杂类型,则按照XmlSchemaComplexType-> XmlSchemaSequence-> XmlSchemaElement的层次进行解析,因为XmlSchemaElement可能任然是复杂类型,所以需要进一步判断递归调用Search。如图6,图7
    if (type instanceof XmlSchemaComplexType) {
        XmlSchemaComplexType xmlSchemaComplexType = (XmlSchemaComplexType) type;
        XmlSchemaParticle xmlSchemaParticle = xmlSchemaComplexType.getParticle();
        if (xmlSchemaParticle instanceof XmlSchemaSequence) {
            XmlSchemaSequence xmlSchemaSequence = (XmlSchemaSequence) xmlSchemaParticle;
            XmlSchemaObjectCollection xmlSchemaObjectCollection = xmlSchemaSequence.getItems();
            int count = xmlSchemaObjectCollection.getCount();
            for (int i = 0; i < count; i++) {
                XmlSchemaObject xmlSchemaObject = xmlSchemaObjectCollection.getItem(i);
                if (xmlSchemaObject instanceof XmlSchemaElement) {
                    XmlSchemaElement xmlSchemaElement = (XmlSchemaElement) xmlSchemaObject;
                    String elementName = xmlSchemaElement.getName();
                    XmlSchemaType xmlSchemaType = xmlSchemaElement.getSchemaType();
                    String elementTypeName = xmlSchemaType.getName();
                    if(elementTypeName!=null){
                        value.add(elementName);
                    }
                    search(xmlSchemaType);
                }
            }
        }
        else {//如果这层不是XmlSchemaSequence则直接获取相应的XmlSchemaAttribute如图7
            XmlSchemaObjectCollection xmlSchemaObjectCollection=xmlSchemaComplexType.getAttributes();
            int count_att = xmlSchemaObjectCollection.getCount();
            for (int j = 0; j < count_att; j++) {
                XmlSchemaObject xmlSchemaObject = xmlSchemaObjectCollection.getItem(j);
                if (xmlSchemaObject instanceof XmlSchemaAttribute) {
                    XmlSchemaAttribute xmlSchemaAttribute = (XmlSchemaAttribute) xmlSchemaObject;
                    String attributeName = xmlSchemaAttribute.getName();
                    QName xmlSchemaTypename = xmlSchemaAttribute.getSchemaTypeName();
                    String atttype=xmlSchemaTypename.getLocalPart();
                    value.add(attributeName);
                }
            }
        }
    }
}

WSDL文件复杂类型的解析及其实例化代码生成_第3张图片
图 6 WSDL层次_element->complexType->sequence->element
WSDL文件复杂类型的解析及其实例化代码生成_第4张图片
图 7 WSDL层次结构_复杂类型解析

3.WSDLcomplexType解析说明

WSDL文件复杂类型的解析及其实例化代码生成_第5张图片
通过对WSDL文件标签类型的判断,采用递归的思想,对自定义类型ESBEnvelope进行多层解析,直到得到基本类型的变量如Appcode等。
根据对WSDL的解析可以得到内部定义的类的结构,如图左边,对自定义类ESBEnvelope对象的“new以及赋值”相关代码的生成过程可以等效成图右边,类的结构定义可以等效成树的结构。

4.自定义类的对象实例化代码生成

因此对象实例化的代码,可以在WSDL的解析过程中,采用深度优先搜索算法(DFS),进行代码生成。如下图
WSDL文件复杂类型的解析及其实例化代码生成_第6张图片

5.demo展示及其说明

Step1:如图2,URL栏目中输入目标WebService的地址,如(http://172.168.1.134/MyWebService.asmx?wsdl),然后点击getValueFromWSDL按钮,得到如图3的界面,此时已经将WebService的方法选项导入到function下拉列表框中,以及WebService内部可能需要赋值的参数全部导入到界面中。
Step2:function下拉列表框中选择需要调用的函数;
Value文本框中写入传递参数的名称;
图3中 在相应标签后边文本框中写入需要传递的参数值,如PassWord右边空白文本框中填写 123456;
填写完毕后,点击Generate,生成所需代码,如图4。
Step3:ctrl+A全选文本编辑区域的文本;
点击copy按钮或者ctrl+c 对选中文本进行复制
将复制代码粘贴找Kettle UDJC模块中的代码编辑区域。
WSDL文件复杂类型的解析及其实例化代码生成_第7张图片
WSDL文件复杂类型的解析及其实例化代码生成_第8张图片
WSDL文件复杂类型的解析及其实例化代码生成_第9张图片

你可能感兴趣的:(web,service,WSDL解析)