我对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>
所以,我想要的值是来自State
的{{1}},我使用此代码:
PostalAddress
一切都很好。
2. 问题从这一点开始,我会像上面一样做,但现在使用这个XML ......
XML文档摘要(其他):
String state = xml.getRequest().getOrderRequest().getOrderRequestHeader().getShipTo().getAddress().getPostalAddress().getState();
//This will return "Value 3"
嗯,我知道该值不存在,但我不想对我的代码进行任何更改,仍然使用它:
<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();
并停止该过程。我需要的是不要停止进程,因为这不是我从XML中提取的唯一值(这只是我正在处理的一个例子)。因此,如果无法找到该值,那么我希望我的NullPointerException
变量自动为state
。
问:如果无法找到值,是否有办法不生成和异常,并使我的字符串变量null
只是state
?< / em>
PS。可能的解决方案可能是这样做:
null
但我不想为我的XML的每个实体制作一个//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();
语句。正如我所说的,我想要一些自动化的东西而不修改代码,我不知道是否有一些JAXB配置或者为此做些什么。
提前致谢。
答案 0 :(得分:1)
JAXB (JSR-222)是用于将对象转换为XML或从XML转换对象的Java标准。有多个开源实现。 JAXB使用的对象是POJO(普通的旧Java对象)。这些类中没有任何类型的XML逻辑。由于JAXB旨在与现有类一起使用,因此可能会有一些逻辑可以用来支持您的用例。以下是几个选项。
选项#1 - 延迟加载PostalAddress属性(不推荐)
的地址强> 的
如果属性为getPostalAddress()
,您可以向PostalAddress
方法添加逻辑以实例化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;
}
}
的的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 - 如果属性为空则返回新实例(不推荐)
的地址强> 的
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 - 在调用之前检查值是否为空
这个选项稍微有些工作,但最终会使您的应用程序更容易维护。