У меня возникла проблема при попытке десериализации xml с помощью jackson.
Я использую следующую функцию для десериализации моего 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();
}
Объект настроек Я использую это десериализацию в: -
https://github.com/Eno-Gerguri/Pygame-Studio/blob/master/src/com/pygame_studio/settings/Settings.java
Подкласс, который использует объект Settings:
https://github.com/Eno-Gerguri/Pygame-Studio/blob/master/src/com/pygame_studio/settings/appearance_and_behavior/AppearanceAndBehavior.java
Подкласс, который использует объект настроек:
https://github.com/Eno-Gerguri/Pygame-Studio/blob/master/src/com/pygame_studio/settings/appearance_and_behavior/Font.java
Когда я пытаюсь десериализовать объект в отдельный файл:
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 в объект «Настройки»?
Заранее спасибо!