[英]Can't call “get” on null value in JAXB generated model
我对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>
因此,我想要的值是PostalAddress
的State
,我使用以下代码:
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
。
问:是否有一种方法不产生异常,如果找不到值,使我的字符串变量state
null
?
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();
但是我不喜欢为我的XML的每个实体都做一个if
语句。 就像我说的那样,我希望无需修改代码就可以实现自动化,并且我不知道是否需要一些JAXB配置或为此执行某些操作。
提前致谢。
JAXB(JSR-222)是用于将对象与XML相互转换的Java标准。 有多种开源实现。 JAXB使用的对象是POJO(普通的Java对象)。 这些类中没有任何XML逻辑。 由于JAXB旨在与现有类一起使用,因此可能存在一些逻辑可以支持您的用例。 以下是几个选项。
选项#1-延迟加载PostalAddress属性(不推荐)
地址
如果属性为null
则可以向getPostalAddress()
方法添加逻辑以实例化PostalAddress
的实例。
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之前检查值不为空
这个选项还有点工作,但是最终将使您的应用程序更易于维护。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.