首页 > 解决方案 > Java - XML 反序列化

问题描述

我需要像这样发出 XML 肥皂请求:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <authenticate xmlns="*Request endpoint*">
        <userName xmlns="">*Personal Information*</userName>
        <password xmlns="">*Personal Information*</password>
    </authenticate>
</s:Body>
</s:Envelope>

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <getFullCustomerInfo xmlns="*Request endpoint*">
        <customerNumber xmlns="">*Personal Information*</customerNumber>
        <sessionKey xmlns="">*Session key*</sessionKey>
    </getFullCustomerInfo>
</s:Body>
</s:Envelope>

我需要将其反序列化为 XML 字符串,我该怎么做?我尝试使用带有命名空间属性的 Jackson XML Databind 库反序列化,但它无法正常工作。

我试图用以下对象反序列化它:

用户名.class

@Setter
public class Username {
    @JacksonXmlProperty(isAttribute = true, localName = "xmlns")
    private String xmlns = "";

    @Setter
    @JacksonXmlProperty(localName = "userName")
    private String username;
}

密码.class

@Setter
public class Password {
    @JacksonXmlProperty(isAttribute = true, localName = "xmlns")
    private String xmlns = "";

    @Setter
    @JacksonXmlProperty(localName = "password")
    private String password;
}

认证.class

public class Authenticate {
    @JacksonXmlProperty(localName = "xmlns", isAttribute = true)
    private String xmlns = *Request Endpoint*;

    @Setter
    @JacksonXmlElementWrapper(useWrapping = false)
    @JacksonXmlProperty(localName = "userName")
    private Username username;

    @Setter
    @JacksonXmlElementWrapper(useWrapping = false)
    @JacksonXmlProperty(localName = "password")
    private Password password;
}

AuthenticationRequest.class

@JacksonXmlRootElement(localName = "Envelope", namespace = "s")
public class AuthenticationRequest {
    @Setter
    @JacksonXmlProperty(localName = "Body", namespace = "s")
    private AuthenticationRequestBody gwpAuthenticationRequestBody;

    @JacksonXmlProperty(isAttribute = true, localName = "xmlns", namespace = "s")
    private String xmlns = "http://schemas.xmlsoap.org/soap/envelope/";
}

AuthenticationRequestBody.class

public class AuthenticationRequestBody {
    @JacksonXmlProperty(isAttribute = true, localName = "xmlns", namespace = "xsi")
    private String xsi = "http://www.w3.org/2001/XMLSchema-instance";

    @JacksonXmlProperty(isAttribute = true, localName = "xmlns", namespace = "xsd")
    private String xsd = "http://www.w3.org/2001/XMLSchema";

    @Setter
    @JacksonXmlProperty(localName = "authenticate")
    private Authenticate authenticate;
}

最终,反序列化的结果是 JsonMappingException:"Multiple fields representing property "xmlns": *PathRoot*.AuthenticationRequestBody#xsi vs *PathRoot*.AuthenticationRequestBody#xsd"

当我像这样更改 AuthenticationRequestBody.class 时:

public class AuthenticationRequestBody {
    @JacksonXmlProperty(isAttribute = true, localName = "xsi", namespace = "xmlns")
    private String xsi = "http://www.w3.org/2001/XMLSchema-instance";

    @JacksonXmlProperty(isAttribute = true, localName = "xsd", namespace = "xmlns")
    private String xsd = "http://www.w3.org/2001/XMLSchema";

    @Setter
    @JacksonXmlProperty(localName = "authenticate")
    private Authenticate authenticate;
}

我得到这样的结果:

<Envelope
    xmlns="s"
    xmlns:wstxns1="s" wstxns1:
    xmlns="http://schemas.xmlsoap.org/soap/envelope/">
    <Body
        xmlns:wstxns2="xmlns" wstxns2:xsi="http://www.w3.org/2001/XMLSchema-instance" wstxns2:xsd="http://www.w3.org/2001/XMLSchema">
        <authenticate
            xmlns=""
            xmlns="*Request Endpoint*">
            <userName
                xmlns="">
                <userName>*Personal Information*</userName>
            </userName>
            <password
                xmlns="">
                <password>*Personal Information*</password>
            </password>
        </authenticate>
    </Body>
</Envelope>

当我执行请求时,我遇到了肥皂故障:

<env:Envelope
    xmlns:env='http://schemas.xmlsoap.org/soap/envelope/'>
    <env:Header></env:Header>
    <env:Body>
        <env:Fault
            xmlns:env='http://schemas.xmlsoap.org/soap/envelope/'>
            <faultcode>env:Client</faultcode>
            <faultstring>org.xml.sax.SAXParseException: Attribute &quot;xmlns&quot; bound to namespace &quot;http://www.w3.org/2000/xmlns/&quot; was already specified for element &quot;authenticate&quot;.</faultstring>
        </env:Fault>
    </env:Body>
</env:Envelope>

标签: javaxmlspringsoapjackson-databind

解决方案


推荐阅读