我目前正在尝试使用JAXB将一些XML解组为java对象,并且我得到一个奇怪的Null指针异常。解组时这只是一个问题。我可以和这些课程一起训练。以下是相关的代码片段(不相关的部分用“......”表示):
JAXB Root元素:
...
@XmlRootElement(name="assets")
public class Assets {
String product;
Images images = new Images();
...
Public Assets() {}
...
public String getProduct() { return this.product; }
@XmlAttribute(name="product")
public void setProduct(String newProduct) { this.product = newProduct; }
public Images getImages() { return this.images; }
@XmlElement(name="images")
public void setImages(Images newImages) { this.images = newImages; }
...
}
根元素的Images子元素:
...
@XmlRootElement(name="images")
@XmlSeeAlso(Image.class)
@XmlType(propOrder = {"mainAsset", "image"})
public class Images {
List<Image> images;
Image mainAsset;
private static char counter = 'a';
private static final String prefix = "product-image-";
// Here's the part that causes the NPE
@XmlAnyElement(lax=true)
public List<JAXBElement<Image>> getImage() {
final List<JAXBElement<Image>> imageList = new ArrayList<JAXBElement<Image>>();
for (final Image g : this.images) {
imageList.add(new JAXBElement(new QName(prefix + counter++), Image.class, g));
}
counter = 'a';
return imageList;
}
@XmlElement(name="renditions")
public void setImage(List<Image> newImages) { this.images = newImages; }
public Image getMainAsset() { return this.mainAsset; }
@XmlElement(name="main-asset-name")
public void setMainAsset(Image newMainAsset) { this.mainAsset = newMainAsset; }
}
解组XML的逻辑:
...
public void modifyXML() {
try {
JAXBContext context = JAXBContext.newInstance(Assets.class, Images.class, Image.class);
Unmarshaller um = context.createUnmarshaller();
File f = new File("/path/to/my.xml");
Assets assets = (Assets) um.unmarshal(f);
...
} catch (JAXBException e) {
e.printStackTrace();
}
}
...
最后,我试图解组的XML(可能有助于知道这个xml文件实际上是使用JAXB marshaller生成的,它运行没有任何问题):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assets product="TEST PRODUCT">
<images>
<main-asset-name>
<path>stuff.jpg</path>
<title>theTitle</path>
<alt>theAlt</path>
<description>theDescription</description>
</main-asset-name>
<product-image-a>
<path>48x48.jpg</path>
<title>theTitle</path>
<alt>theAlt</path>
<description>theDescription</description>
</product-image-a>
<product-image-b>
<path>140x140.jpg</path>
<title>theTitle</path>
<alt>theAlt</path>
<description>theDescription</description>
</product-image-b>
<product-image-c>
<path>1280x1280.jpg</path>
<title>theTitle</path>
<alt>theAlt</path>
<description>theDescription</description>
</product-image-c>
<product-image-d>
<path>319x319.jpg</path>
<title>theTitle</path>
<alt>theAlt</path>
<description>theDescription</description>
</product-image-d>
</images>
</assets>
好的,这就是所有相关代码(我认为)。当我运行我的程序时,我在调用unmarshaller之后立即收到以下错误:
java.lang.NullPointerException
at com.my.companys.name.Images.getImage(Images.java:25)
引用的行号是for循环在我的Images.java
类文件中开始的行。
有没有人知道为什么this.images
可能在这里为空?任何帮助是极大的赞赏。提前谢谢。
答案 0 :(得分:0)
这是我一直在使用的解决方案。这是一个黑客攻击,但地狱......它完成了这项工作。
首先,我将原始xml作为字符串而不是将其作为文件读取:
public void modifyXML() {
try {
JAXBContext context = JAXBContext.newInstance(Assets.class, Image.class);
Unmarshaller um = context.createUnmarshaller();
// This xml should be formatted in a way that JAXB can work with
String rawXML = getRawXML("/path/to/my.xml");
// Hand the modified xml to the unmarshaller
Assets umAssets = (Assets) um.unmarshal(new StreamSource(new StringReader(rawXML)));
// Do stuff with umAssets
...
} catch (Exception e) {
e.printStackTrace();
}
}
private String getRawXML(String path) throws IOException {
String xml = readFile(path, StandardCharsets.UTF_8);
// This should make it so JAXB can handle the xml properly
xml = xml.replaceAll("<main-asset-name>", "<image>");
xml = xml.replaceAll("</main-asset-name>", "</image>");
xml = xml.replaceAll("<product-image.*>", "<image>");
return xml.replaceAll("</product-image.*>", "</image>");
}
private String readFile(String path, Charset encoding) throws IOException {
// A simple file reader
byte[] encoded = Files.readAllBytes(Paths.get(path));
return new String(encoded, encoding);
}
这似乎可以解决问题,所以我现在要使用它。当然,如果有人有解决方案,我仍然愿意接受更好的解决方案。