XML JAXB 编组未保存到 xml 文件
XML JAXB marshall not saving to xml file
我有一个 javafx 程序,它会调出一个文件选择器,以允许用户选择并将其成像显示到网格视图中,并插入一个在选择图像后弹出的标题。我将文件路径和标题保存到不同的数组列表 [暂时],我的目标是将两者都保存到 xml 文件,这样我可以在重新打开应用程序时解组它,这样图像仍然存在。现在我只想将这两个字符串保存到一个 xml 文件中,然后再找出其余的。我目前能够 运行 我的代码没有错误,直到我到达我的停止方法,我尝试保存用户添加到数组列表的每个图像和标题。
我的 JAXB 注释:
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class ImageCap {
private String filePath;
private String caption;
public ImageCap() {
}
public ImageCap(String filePath, String caption) {
this.filePath = filePath;
this.caption = caption;
}
@Override
public String toString() {
return "ImageCap{" + "filePath=" + filePath + ", caption=" + caption + '}';
}
public String getFilePath() {
return filePath;
}
@XmlElement
public void setFilePath(String filePath) {
this.filePath = filePath;
}
public String getCaptions() {
return caption;
}
@XmlElement
public void setCaption(String caption) {
this.caption = caption;
}
}
还有我要测试的主要内容:
public static void main(String[] args) {launch(args);}
public void start(Stage primaryStage) throws JAXBException{
final JFXPanel bananarama = new JFXPanel();
//import the library (read))
// create the (initial) display
display.makeBrowseButton(primaryStage);
display.createDisplay(primaryStage);
// show user
primaryStage.show();
}@Override
public void stop() throws JAXBException{
File file = new File("file.xml");
JAXBContext jaxbContext = JAXBContext.newInstance(ImageCap.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
//this.context = JAXBContext.newInstance(ImageCap.class);
//Marshaller marshaller = context.createMarshaller();
for(int i = 0; i < display.filePaths.size(); i++)
{
ImageCap imageCap = new ImageCap();
imageCap.setFilePath(display.filePaths.get(i));
imageCap.setCaption(display.captions.get(i).toString());
System.out.println(display.filePaths.get(i).toString());
try {
// output pretty printed
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
jaxbMarshaller.marshal(imageCap, file);
} catch (JAXBException e) {
e.printStackTrace();
}
}
}
这是停止命令后我的错误:
this problem is related to the following location:
at public void ImageCap.setCaption(java.lang.String)
at ImageCap
this problem is related to the following location:
at private java.lang.String ImageCap.caption
at ImageCap
Class has two properties of the same name "filePath"
this problem is related to the following location:
at public java.lang.String ImageCap.getFilePath()
at ImageCap
this problem is related to the following location:
at private java.lang.String ImageCap.filePath
at ImageCap
但它特别在第 81 行中断:
JAXBContext jaxbContext = JAXBContext.newInstance(ImageCap.class);
有什么想法吗?
如果您有 getter 和同名字段的设置器,则需要使用 XmlAccessType.PROPERTY
而不是 XmlAccessType.FIELD
:
@XmlRootElement
@XmlAccessorType(XmlAccessType.PROPERTY)
public static class ImageCap {
private String filePath;
private String caption;
...
此外,您会遇到的另一个问题是您将 getCaption
s
()
拼错为复数,而实际上应该是 getCaption()
。 JAXB 也会抱怨它。
最后,通过在循环内编组您的文件,您将用当前处理的 imageCap
一遍又一遍地重写同一个文件。如果您想要编组所有 imageCap
,则需要将它们放在 List
上,然后编组 List
。为此,您需要一个新的 JAXB 模型 class,例如:
@XmlRootElement(name = "myImageCapList")
class ImageCapList {
@XmlElement
List<ImageCap> imageCap;
public ImageCapList() {}
public ImageCapList(List<ImageCap> imageCaps) {
this.imageCap = imageCaps;
}
}
并且您需要创建此对象的实例来包装您的 ImageCap
对象列表 (List<ImageCap>
) 并将其用作调用 jaxbMarshaller.marshal
方法的目标如下方法所示:
public void imageCapsMarshal(List<ImageCap> imageCaps, File outFile) {
try {
jaxbMarshaller.marshal(new ImageCapList(imageCaps), outFile);
} catch (JAXBException e) {
// HANDLE EXCEPTIONS
}
}
此外,您需要适当地实例化您的 JAXBContext
:
jaxbContext = JAXBContext.newInstance(ImageCapList.class);
下面是一个完整的工作演示,供您试用:
import java.io.File;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
public class JAXBMarshall {
private JAXBContext jaxbContext;
private Marshaller jaxbMarshaller;
public JAXBMarshall() throws JAXBException {
jaxbContext = JAXBContext.newInstance(ImageCapList.class);
jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
}
public void imageCapsMarshal(List<ImageCap> imageCaps, File outFile) {
try {
jaxbMarshaller.marshal(new ImageCapList(imageCaps), outFile);
} catch (JAXBException e) {
// HANDLE EXCEPTIONS
}
}
public static void main(String[] args) throws JAXBException {
JAXBMarshall jaxbMarshaller = new JAXBMarshall();
File file = new File("file.xml");
List<ImageCap> imageCaps = IntStream.range(0, 10)
.mapToObj(idx -> new ImageCap("my/file/path/" + idx, idx + ". The Caption!"))
.collect(Collectors.toList());
jaxbMarshaller.imageCapsMarshal(imageCaps, file);
}
@XmlRootElement(name = "myImageCapList")
static class ImageCapList {
@XmlElement
List<ImageCap> imageCap;
public ImageCapList() {}
public ImageCapList(List<ImageCap> imageCaps) {
this.imageCap = imageCaps;
}
}
@XmlRootElement
static class ImageCap {
@XmlElement
String filePath;
@XmlElement
String caption;
public ImageCap() {}
public ImageCap(String filePath, String caption) {
this.filePath = filePath;
this.caption = caption;
}
@Override
public String toString() {
return "ImageCap{" + "filePath=" + filePath + ", caption=" + caption + '}';
}
}
}
希望这对您有所帮助。
我有一个 javafx 程序,它会调出一个文件选择器,以允许用户选择并将其成像显示到网格视图中,并插入一个在选择图像后弹出的标题。我将文件路径和标题保存到不同的数组列表 [暂时],我的目标是将两者都保存到 xml 文件,这样我可以在重新打开应用程序时解组它,这样图像仍然存在。现在我只想将这两个字符串保存到一个 xml 文件中,然后再找出其余的。我目前能够 运行 我的代码没有错误,直到我到达我的停止方法,我尝试保存用户添加到数组列表的每个图像和标题。
我的 JAXB 注释:
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class ImageCap {
private String filePath;
private String caption;
public ImageCap() {
}
public ImageCap(String filePath, String caption) {
this.filePath = filePath;
this.caption = caption;
}
@Override
public String toString() {
return "ImageCap{" + "filePath=" + filePath + ", caption=" + caption + '}';
}
public String getFilePath() {
return filePath;
}
@XmlElement
public void setFilePath(String filePath) {
this.filePath = filePath;
}
public String getCaptions() {
return caption;
}
@XmlElement
public void setCaption(String caption) {
this.caption = caption;
}
}
还有我要测试的主要内容:
public static void main(String[] args) {launch(args);}
public void start(Stage primaryStage) throws JAXBException{
final JFXPanel bananarama = new JFXPanel();
//import the library (read))
// create the (initial) display
display.makeBrowseButton(primaryStage);
display.createDisplay(primaryStage);
// show user
primaryStage.show();
}@Override
public void stop() throws JAXBException{
File file = new File("file.xml");
JAXBContext jaxbContext = JAXBContext.newInstance(ImageCap.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
//this.context = JAXBContext.newInstance(ImageCap.class);
//Marshaller marshaller = context.createMarshaller();
for(int i = 0; i < display.filePaths.size(); i++)
{
ImageCap imageCap = new ImageCap();
imageCap.setFilePath(display.filePaths.get(i));
imageCap.setCaption(display.captions.get(i).toString());
System.out.println(display.filePaths.get(i).toString());
try {
// output pretty printed
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
jaxbMarshaller.marshal(imageCap, file);
} catch (JAXBException e) {
e.printStackTrace();
}
}
}
这是停止命令后我的错误:
this problem is related to the following location:
at public void ImageCap.setCaption(java.lang.String)
at ImageCap
this problem is related to the following location:
at private java.lang.String ImageCap.caption
at ImageCap
Class has two properties of the same name "filePath"
this problem is related to the following location:
at public java.lang.String ImageCap.getFilePath()
at ImageCap
this problem is related to the following location:
at private java.lang.String ImageCap.filePath
at ImageCap
但它特别在第 81 行中断:
JAXBContext jaxbContext = JAXBContext.newInstance(ImageCap.class);
有什么想法吗?
如果您有 getter 和同名字段的设置器,则需要使用 XmlAccessType.PROPERTY
而不是 XmlAccessType.FIELD
:
@XmlRootElement
@XmlAccessorType(XmlAccessType.PROPERTY)
public static class ImageCap {
private String filePath;
private String caption;
...
此外,您会遇到的另一个问题是您将 getCaption
s
()
拼错为复数,而实际上应该是 getCaption()
。 JAXB 也会抱怨它。
最后,通过在循环内编组您的文件,您将用当前处理的 imageCap
一遍又一遍地重写同一个文件。如果您想要编组所有 imageCap
,则需要将它们放在 List
上,然后编组 List
。为此,您需要一个新的 JAXB 模型 class,例如:
@XmlRootElement(name = "myImageCapList")
class ImageCapList {
@XmlElement
List<ImageCap> imageCap;
public ImageCapList() {}
public ImageCapList(List<ImageCap> imageCaps) {
this.imageCap = imageCaps;
}
}
并且您需要创建此对象的实例来包装您的 ImageCap
对象列表 (List<ImageCap>
) 并将其用作调用 jaxbMarshaller.marshal
方法的目标如下方法所示:
public void imageCapsMarshal(List<ImageCap> imageCaps, File outFile) {
try {
jaxbMarshaller.marshal(new ImageCapList(imageCaps), outFile);
} catch (JAXBException e) {
// HANDLE EXCEPTIONS
}
}
此外,您需要适当地实例化您的 JAXBContext
:
jaxbContext = JAXBContext.newInstance(ImageCapList.class);
下面是一个完整的工作演示,供您试用:
import java.io.File;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
public class JAXBMarshall {
private JAXBContext jaxbContext;
private Marshaller jaxbMarshaller;
public JAXBMarshall() throws JAXBException {
jaxbContext = JAXBContext.newInstance(ImageCapList.class);
jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
}
public void imageCapsMarshal(List<ImageCap> imageCaps, File outFile) {
try {
jaxbMarshaller.marshal(new ImageCapList(imageCaps), outFile);
} catch (JAXBException e) {
// HANDLE EXCEPTIONS
}
}
public static void main(String[] args) throws JAXBException {
JAXBMarshall jaxbMarshaller = new JAXBMarshall();
File file = new File("file.xml");
List<ImageCap> imageCaps = IntStream.range(0, 10)
.mapToObj(idx -> new ImageCap("my/file/path/" + idx, idx + ". The Caption!"))
.collect(Collectors.toList());
jaxbMarshaller.imageCapsMarshal(imageCaps, file);
}
@XmlRootElement(name = "myImageCapList")
static class ImageCapList {
@XmlElement
List<ImageCap> imageCap;
public ImageCapList() {}
public ImageCapList(List<ImageCap> imageCaps) {
this.imageCap = imageCaps;
}
}
@XmlRootElement
static class ImageCap {
@XmlElement
String filePath;
@XmlElement
String caption;
public ImageCap() {}
public ImageCap(String filePath, String caption) {
this.filePath = filePath;
this.caption = caption;
}
@Override
public String toString() {
return "ImageCap{" + "filePath=" + filePath + ", caption=" + caption + '}';
}
}
}
希望这对您有所帮助。