0

我对 JAXB 不太熟悉,但这是我所拥有的上下文,请阅读所有内容以了解。

1.我正在执行以下操作以使用此 XML 中的 JAXB 获取值...

XML 文档片段(原始):

 <Request deploymentMode="production">
        <OrderRequest>
             <OrderRequestHeader orderID="12345" orderDate="2012-07-04" type="new">
                 <Total>
                     <Money currency="USD">200.0</Money>
                 </Total>
                 <ShipTo>
                     <Address>
                         <Name xml:lang="">Test</Name>
                         <PostalAddress name="default">
                             <DeliverTo/>
                             <Street>Value 1</Street>
                             <City>Value 2</City>
                             <State>Value 3</State>
                             <PostalCode>302010</PostalCode>
                             <Country isoCountryCode="US">USA</Country>
                         </PostalAddress>
                     </Address>
                 </ShipTo>

因此,我想要的值是Statefrom PostalAddress,我使用以下代码:

String state = xml.getRequest().getOrderRequest().getOrderRequestHeader().getShipTo().getAddress().getPostalAddress().getState();
//This will return "Value 3"

一切都很好。

2.问题从这里开始,我会做和上面一样的事情,但是现在使用这个XML......

XML 文档片段(其他):

 <Request deploymentMode="production">
        <OrderRequest>
             <OrderRequestHeader orderID="12345" orderDate="2012-07-04" type="new">
                 <Total>
                     <Money currency="USD">200.0</Money>
                 </Total>
                 <ShipTo>
                     <Address>
                         <Name xml:lang="">Test</Name>
                     </Address>
                 </ShipTo>

好吧,我知道该值不存在,但我不想对我的代码进行任何更改并仍在使用它:

String state = xml.getRequest().getOrderRequest().getOrderRequestHeader().getShipTo().getAddress().getPostalAddress().getState();

上面的代码将产生一个NullPointerException并停止该过程。我需要的是不要停止该过程,因为这不是我从 XML 中提取的唯一值(这只是我正在处理的一个示例)。所以,如果找不到该值,那么我希望我的state变量是null自动的。

问:如果找不到值,有没有办法不产生异常并使我的字符串变量statenull


PS。一个可能的解决方案可能是做这样的事情:

//Fill the entity
PostalAddressType p = xml.getRequest().getOrderRequest().getOrderRequestHeader().getShipTo().getAddress().getPostalAddress();
//Variable for state
String state = null;
//Evaluate if it is null or not
if(p != null)
    //Capture the value if not null
    state = p.getState();

但我不喜欢为if我的 XML 的每个实体做一个声明。正如我所说,我希望在不修改代码的情况下实现自动化,我不知道是否有一些 JAXB 配置或为此做些什么。

提前致谢。

4

1 回答 1

1

JAXB (JSR-222)是用于将对象与 XML 相互转换的 Java 标准。有多种开源实现。JAXB 使用的对象是 POJO(普通的旧 Java 对象)。这些类中没有任何类型的 XML 逻辑。由于 JAXB 旨在与现有类一起使用,因此可能会制定一些逻辑来支持您的用例。下面是几个选项。

选项 #1 - 延迟加载 PostalAddress 属性(不推荐)

地址

您可以向该方法添加逻辑以getPostalAddress()实例化PostalAddressif 属性的实例null

package forum11333165;

import javax.xml.bind.annotation.*;

@XmlRootElement(name="Address")
public class Address {

    private String name;
    private PostalAddress postalAddress;

    @XmlElement(name="Name")
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @XmlElement(name="PostalAddress")
    public PostalAddress getPostalAddress() {
        if(null == postalAddress) {
            postalAddress = new PostalAddress();
        }
        return postalAddress;
    }

    public void setPostalAddress(PostalAddress postalAddress) {
        this.postalAddress = postalAddress;
    }

}

邮寄地址

package forum11333165;

import javax.xml.bind.annotation.XmlElement;

public class PostalAddress {

    private String state;

    @XmlElement(name="State")
    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

}

演示

下面的演示代码演示了您将能够

package forum11333165;

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

public class Demo {

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

        StringReader xml = new StringReader("<Address><Name>Test</Name></Address>");
        Unmarshaller unmarshaller = jc.createUnmarshaller();
        Address address = (Address) unmarshaller.unmarshal(xml);

        System.out.println(address.getPostalAddress().getState());

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(address, System.out);
    }

}

输出

下面是运行演示代码的输出。如您所见,我们得到了null我们正在寻找的值,但输出包含一个额外的PostalAddress方法。

null
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Address>
    <Name>Test</Name>
    <PostalAddress/>
</Address>

选项 #2 - 如果属性为 Null,则返回一个新实例(不推荐)

地址

package forum11333165;

import javax.xml.bind.annotation.*;

@XmlRootElement(name="Address")
@XmlAccessorType(XmlAccessType.FIELD)
public class Address {

    @XmlElement(name="Name")
    private String name;

    @XmlElement(name="PostalAddress")
    private PostalAddress postalAddress;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public PostalAddress getPostalAddress() {
        if(null == postalAddress) {
            return new PostalAddress();
        }
        return postalAddress;
    }

    public void setPostalAddress(PostalAddress postalAddress) {
        this.postalAddress = postalAddress;
    }

}

输出

我们可以使用与上一个选项相同的演示代码来生成新的输出。get 仍然有效,我们没有得到额外的PostalAddress方法。不利的一面是我们认为我们设置的状态没有被捕获。

null
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Address>
    <Name>Test</Name>
</Address>  

选项 #3 - 在调用 Get On 之前检查值不为空

这个选项需要做更多的工作,但最终会使您的应用程序更易于维护。

于 2012-07-04T21:05:05.613 回答