1

我正在尝试使用 JAXWS 和 wsimport 使用 Web 服务。WSIMPORT 工具生成了所有必需的类,我可以毫无问题地调用该服务。

但是,我注意到在响应包含具有有效属性值的 nil 元素的情况下,JAXWS 无法解组它并抛出 NullPointerException。我使用 SOAP UI 来帮助调试,这就是我发现的。响应返回以下 XML(摘录):

            <externalIdentifiers>
                 <identifierType code="2" name="Passport" xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
                 <identifierValue/>
                 <issuingCountry xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
              </externalIdentifiers>

在我的 Java 代码中,当尝试读取上述标识符类型的“名称”属性时,它会引发 NPE:

      if(id.getIdentifierType() == null)
            {
                System.out.println("NULL");
            }
            System.out.println("Identifier Type: " + id.getIdentifierType().getName());

输出:

NULL
Exception in thread "main" java.lang.NullPointerException

对我来说,这看起来是一个合理的响应,因为在响应中,identifierType 设置为 xsi:nil="true"。根据 W3C,这也是完全有效的 XML。问题是,在这种情况下如何读取代码和名称等属性值?

4

1 回答 1

0

以下是支持此用例的方法:

Java 模型

外部标识符

您可以将identifierType属性更改为 typeJAXBElement<IdentifierType>而不是IdentifierType. 为此,您需要使用 注释属性@XmlElementRef

import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.*;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class ExternalIdentifiers {

    @XmlElementRef(name="identifierType")
    private JAXBElement<IdentifierType> identifierType;

    public JAXBElement<IdentifierType> getIdentifierType() {
        return identifierType;
    }

}

对象工厂

您将需要在使用 注释的类中的 e 方法@XmlElementDecl上进行相应的注释。creat@XmlRegistry

import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.*;
import javax.xml.namespace.QName;

@XmlRegistry
public class ObjectFactory {

    @XmlElementDecl(name="identifierType")
    public JAXBElement<IdentifierType> createIdentifierType(IdentifierType identifierType) {
        return new JAXBElement(new QName("identifierType"), IdentifierType.class, identifierType);
    }

}

演示代码

输入.xml

<?xml version="1.0" encoding="UTF-8"?>
<externalIdentifiers>
    <identifierType code="2" name="Passport" xsi:nil="true"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
</externalIdentifiers>

演示

import java.io.File;
import javax.xml.bind.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(ExternalIdentifiers.class, ObjectFactory.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("src/forum18834036/input.xml");
        ExternalIdentifiers externalIdentifiers = (ExternalIdentifiers) unmarshaller.unmarshal(xml);

        System.out.println(externalIdentifiers.getIdentifierType().getValue().getName());
    }

}

输出

Passport

笔记

目前在EclipseLink JAXB (MOXy)中有一个关于这个用例的错误:

于 2013-09-16T19:20:18.493 回答