java - 使用jackson反序列化xml时未初始化Java静态变量
问题描述
尝试使用 jackson 反序列化 xml 时遇到问题。
我正在使用以下函数从文件中反序列化我的 xml。
Xml 文件如下:
https://github.com/Eno-Gerguri/Pygame-Studio/blob/master/Settings/defaultSettings.xml
这是我用来反序列化对象的函数:
public Settings deserializeSettings(File settingsFile) {
XmlMapper xmlMapper = new XmlMapper();
String xml = null;
Settings settings = null;
try {
xml = inputStreamToString(new FileInputStream(settingsFile));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
settings = xmlMapper.readValue(xml, Settings.class);
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return settings;
}
private String inputStreamToString(InputStream inputStream) throws IOException {
StringBuilder stringBuilder = new StringBuilder();
String line;
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
while ((line = bufferedReader.readLine()) != null) {
stringBuilder.append(line);
}
bufferedReader.close();
return stringBuilder.toString();
}
我正在使用的设置对象反序列化为:-
Settings 对象使用的子类:
Settings 对象使用的子类:
当我尝试在单独的文件中反序列化对象时:
private Settings defaultSettings = settingsManager.deserializeSettings(DefaultSettings.DEFAULT_SETTINGS_FILE_DIRECTORY);
以下错误日志
com.fasterxml.jackson.databind.JsonMappingException: N/A
at [Source: (StringReader); line: 1, column: 356] (through reference chain: com.pygame_studio.settings.Settings["appearanceAndBehavior"]->com.pygame_studio.settings.appearance_and_behavior.AppearanceAndBehavior["font"]->com.pygame_studio.settings.appearance_and_behavior.Font["fontDirectory"])
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:278)
at com.fasterxml.jackson.databind.deser.SettableBeanProperty._throwAsIOE(SettableBeanProperty.java:611)
at com.fasterxml.jackson.databind.deser.SettableBeanProperty._throwAsIOE(SettableBeanProperty.java:599)
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:143)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:288)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:151)
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:129)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:288)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:151)
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:129)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:288)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:151)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4202)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3205)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3173)
at com.pygame_studio.settings.SettingsManager.deserializeSettings(SettingsManager.java:75)
at com.pygame_studio.start_menu.StartMenu.<init>(StartMenu.java:24)
at com.pygame_studio.PygameStudio.<init>(PygameStudio.java:18)
at com.pygame_studio.PygameStudio.main(PygameStudio.java:25)
Caused by: java.lang.NullPointerException
at com.pygame_studio.settings.appearance_and_behavior.Font.setFontDirectory(Font.java:115)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:141)
... 15 more
我知道在函数中:com.pygame_studio.settings.appearance_and_behavior.Font.setFontDirectory
public void setFontDirectory(String fontDirectory) {
if (externalFonts.containsKey(fontDirectory)) {
this.fontDirectory = externalFonts.get(fontDirectory);
} else if (localFonts.contains(fontDirectory)) {
this.fontDirectory = fontDirectory;
} else {
this.fontDirectory = this.getFallbackFont();
}
}
externalFonts Hashtable 为 null,因为它尚未初始化,但它应该与构造函数中的一样:
public Font() {
super();
}
public Font(File externalFontDirectory, String fontName, int fontStyle, int fontSize, String fallbackFont) {
this.setExternalFontDirectory(externalFontDirectory);
this.setExternalFonts(); // External fonts is set before the font directory.
this.setLocalFonts();
this.setFontDirectory(fontName); // Font directory being set after externalFonts.
this.setFontStyle(fontStyle);
this.setFontSize(fontSize);
this.setFallbackFont(fallbackFont);
}
setExternalFonts 方法:
public void setExternalFonts() {
externalFonts = getExternalFonts(this.externalFontDirectory);
}
getExternalFonts 方法:
public static Hashtable<String, String> getExternalFonts(File externalFontDirectory) {
Hashtable<String, String> externalFonts = new Hashtable<>();
final File[] directoryFiles = externalFontDirectory.listFiles();
if (directoryFiles != null) {
for (File file : directoryFiles) {
if (file.isDirectory()) { // If the file is a sub-directory.
externalFonts.putAll(getExternalFonts(file)); // Calls itself onto the directory.
} else if (file.getName().contains(".ttf")) { // If the file is a font.
String fontName = file.getName().replace(".ttf", ""); // Gets the name of the font.
externalFonts.put(fontName, file.getPath()); // Puts the, name of the font : font's directory, into the Hashtable.
}
}
}
return externalFonts;
}
但是,我的 IDE Eclipse 告诉我,当它应该初始化 externalFonts 时,这个代码永远不会到达。
为什么不调用此方法?如何解决此问题,以便成功将 xml 反序列化为“设置”对象?
提前致谢!
解决方案
具体问题在Font
课堂上:
public static Hashtable<String, String> externalFonts;
首先,我建议将其更改Hashtable
为HashMap
- 这些天(根据我的经验)没有理由使用Hashtable
任何更现代的集合类。您可以在此处阅读社区意见。
其次,该字段需要初始化,因此它不为空 - 就像您为localFonts
列表所做的那样。
所以这给了我们这个:
public static Map<String, String> externalFonts = new HashMap();
当然,您随后需要替换对 的剩余引用Hashtable
。
当我进行更改时,它解决了您报告的特定问题。
推荐阅读
- node.js - 如何在不使用 npx 全局安装的情况下从包中运行 cli 命令
- android - 我的 Android 片段代码返回 IllegalStateException,但只有几次
- java - 在 Selenium Webdriver 中将 DesiredCapabilities 与 FirefoxOptions 合并导致 java.lang.NoSuchMethodError
- php - 未设置单选按钮时出现错误
- swift - 使用 NVActivityIndicatorView 和 Timer,它显示的时间很短
- javascript - 来自 mongodb 查找查询的空白结果
- python - 我们可以使用 argcomplete 来完成 bash tab 完成而不在 shell 中编写 python 关键字吗?
- r - paste 如何在函数中工作
- java - 无法在 Oracle 中使用 dbms_java.loadjava 加载 jar
- r - 从列表列表中读入文件