java 解组错误:来自具有旧 WSDL 的旧请求的意外元素

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11560636/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 05:34:39  来源:igfitidea点击:

Unmarshalling Error: unexpected element from legacy request with legacy WSDL

javaxmlsoapwsdljax-ws

提问by m0rv4i

I am receiving a SOAP request from some legacy code, and dealing with it using JAX-WS generated objects from the same WSDL the legacy code uses, but I am getting an Unmarshalling Error: unexpected element error when I process the request.

我收到来自一些遗留代码的 SOAP 请求,并使用来自遗留代码使用的相同 WSDL 的 JAX-WS 生成的对象来处理它,但是我在处理请求时收到一个解组错误:意外的元素错误。

The WSDL part for this request is as follows: (Please note "schema" has replaced all the actual schema locations for our WSDL)

此请求的 WSDL 部分如下:(请注意“模式”已替换了我们 WSDL 的所有实际模式位置)

    <xsd:complexType name="Administrate">
        <xsd:sequence>
            <xsd:element name="AdminOperation" type="typens:AdminOperation" maxOccurs="unbounded" minOccurs="0"/>
        </xsd:sequence>
    </xsd:complexType>
    <xsd:element name="Administrate" type="typens:Administrate"/>
    <xsd:complexType name="AdministrateResponse">
        <xsd:sequence>
        <xsd:element name="Status" type="typens:SoapResponseStatus"/>
        </xsd:sequence>
    </xsd:complexType>
    <xsd:element name="AdministrateResponse" type="typens:AdministrateResponse"/>
    <xsd:complexType name="AdminOperation">
        <xsd:sequence>
            <xsd:choice>
                <xsd:element name="Transaction" type="typens:Transaction" minOccurs="0"/>
                <xsd:element name="CreateUser" type="typens:CreateUser" minOccurs="0"/>
                <xsd:element name="DeleteUser" type="typens:DeleteUser" minOccurs="0"/>
                <xsd:element name="UpdateUser" type="typens:UpdateUser" minOccurs="0"/>
                <xsd:element name="CreateGroup" type="typens:CreateGroup" minOccurs="0"/>
                <xsd:element name="DeleteGroup" type="typens:DeleteGroup" minOccurs="0"/>
                <xsd:element name="UpdateGroup" type="typens:UpdateGroup" minOccurs="0"/>
                <xsd:element name="CreateChannel" type="typens:CreateChannel" minOccurs="0"/>
                <xsd:element name="DeleteChannel" type="typens:DeleteChannel" minOccurs="0"/>
                <xsd:element name="UpdateChannel" type="typens:UpdateChannel" minOccurs="0"/>
                <xsd:element name="CreateRole" type="typens:CreateRole" minOccurs="0"/>
                <xsd:element name="DeleteRole" type="typens:DeleteRole" minOccurs="0"/>
                <xsd:element name="UpdateRole" type="typens:UpdateRole" minOccurs="0"/>
                <xsd:element name="CreateFileType" type="typens:CreateFileType" minOccurs="0"/>
                <xsd:element name="DeleteFileType" type="typens:DeleteFileType" minOccurs="0"/>
                <xsd:element name="UpdateFileType" type="typens:UpdateFileType" minOccurs="0"/>
                <xsd:element name="CreateFolder" type="typens:CreateFolder" minOccurs="0"/>
                <xsd:element name="DeleteFile" type="typens:DeleteFile" minOccurs="0"/>
                <xsd:element name="MoveFile" type="typens:MoveFile" minOccurs="0"/>
                <xsd:element name="CopyFile" type="typens:CopyFile" minOccurs="0"/>
                <xsd:element name="UpdateFile" type="typens:UpdateFile" minOccurs="0"/>
                <xsd:element name="DeleteJob" type="typens:DeleteJob" minOccurs="0"/>
                <xsd:element name="DeleteJobNotices" type="typens:DeleteJobNotices" minOccurs="0"/>
                <xsd:element name="UpdateJobSchedule" type="typens:UpdateJobSchedule" minOccurs="0"/>
                <xsd:element name="UpdateVolumeProperties" type="typens:UpdateVolumeProperties" minOccurs="0"/>
                <xsd:element name="UpdateOpenSecurityCache" type="typens:UpdateOpenSecurityCache" minOccurs="0"/>
            </xsd:choice>
        </xsd:sequence>
    </xsd:complexType>

and the request sent:

和请求发送:

    <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
        SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
        xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
        xmlns:xsd="http://www.w3.org/2000/10/XMLSchema" xmlns="schema">
        <SOAP-ENV:Header>
            <AuthId>7</AuthId>
        </SOAP-ENV:Header>
        <SOAP-ENV:Body>
            <Administrate>
                <UpdateFile>
                    <SetPermissions>
                        <Permission SOAP-ENC:arrayType="Permission[1]">
                            <UserName>username</UserName>
                            <AccessRight>rights</AccessRight>
                        </Permission>
                    </SetPermissions>
                    <NameList>
                        <String>folder1</String>
                        <String>folder1/folder2</String>
                        <String>folder1/folder2/file.ext</String>
                    </NameList>
                </UpdateFile>
            </Administrate>
        </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>

But I get the following error from my code:

但是我从我的代码中得到以下错误:

            <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
                <soap:Body>
                    <soap:Fault>
                        <faultcode>soap:Client</faultcode>
                        <faultstring>Unmarshalling Error: unexpected element
                            (uri:"schema", local:"UpdateFile"). Expected elements
                            are &lt;{schema}AdminOperation> </faultstring>
                    </soap:Fault>
                </soap:Body>
            </soap:Envelope>

The Administrate JAX-WS generated object just contains an ArrayList of AdminOperations with a getter,

管理 JAX-WS 生成的对象只包含一个带有 getter 的 AdminOperations ArrayList,

    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name = "Administrate", propOrder = {
        "adminOperation"
    })
    public class Administrate {

        @XmlElement(name = "AdminOperation")
        protected List<AdminOperation> adminOperation;

        /**
         * Gets the value of the adminOperation property.
         * 
         * <p>
         * This accessor method returns a reference to the live list,
         * not a snapshot. Therefore any modification you make to the
         * returned list will be present inside the JAXB object.
         * This is why there is not a <CODE>set</CODE> method for the adminOperation property.
         * 
         * <p>
         * For example, to add a new item, do as follows:
         * <pre>
         *    getAdminOperation().add(newItem);
         * </pre>
         * 
         * 
         * <p>
         * Objects of the following type(s) are allowed in the list
         * {@link AdminOperation }
         * 
         * 
         */
        public List<AdminOperation> getAdminOperation() {
            if (adminOperation == null) {
                adminOperation = new ArrayList<AdminOperation>();
            }
            return this.adminOperation;
        }

    }

But judging from the legacy request sent and from the WSDL, this operation tag is replaced with choice of operations, e.g. updatefile etc right?

但是从发送的遗留请求和 WSDL 来看,这个操作标签被替换为操作选择,例如更新文件等,对吗?

As I cannot change the legacy request or legacy WSDL, I am unsure as to how to proceed. Any help would be greatly appreciated, so thanks in advance!

由于我无法更改旧请求或旧 WSDL,我不确定如何继续。任何帮助将不胜感激,所以提前致谢!

采纳答案by dcbyers

Your suspicion is correct. In this case, the client is actually sending a request that does not conform to the provided schema.

你的怀疑是正确的。在这种情况下,客户端实际上发送的请求不符合所提供的架构。

Since you have no control of the client code and apparently must accommodate the client, my hope is that it is the only client for this service. The simplest path-forward would be to adjust the service to the contract for which the client has actually been built. You could manually tweak the schema to indicate that UpdateFile is a child of Administrate, then regen the relevant objects or (to not bother with regen of objects) tweak the Administrate java object annotations to reflect FileUpdate as first-level child: ... @XmlType(name = "Administrate", propOrder = { "updateFile" }) public class Administrate {

由于您无法控制客户端代码并且显然必须容纳客户端,因此我希望它是此服务的唯一客户端。最简单的前进路径是将服务调整到实际构建客户端的合同。您可以手动调整架构以指示 UpdateFile 是管理的子项,然后重新生成相关对象或(不要打扰对象的重新生成)调整管理 java 对象注释以将 FileUpdate 反映为一级子项:... @ XmlType(name = "Administrate", propOrder = { "updateFile" }) 公共类管理 {

    @XmlElement(name = "UpdateFile")
    protected UpdateFileType updateFile;

...

...

Due diligence would be to also recognize the other forms of request (do they conform to the contract) to ensure no further breakage when adapting the service endpoint.

尽职调查还将识别其他形式的请求(它们是否符合合同),以确保在调整服务端点时不会进一步破坏。