【发布时间】:2019-02-15 10:25:12
【问题描述】:
我正在尝试编写一个类,该类可以使用 Java 将设置序列化和反序列化为 XML。我已经用 C# 成功编写了这段代码,它非常有用,所以我想在我的 java 应用程序中使用类似的东西。
我有以下基类,我想序列化为 XML 的每个类都必须实现。
package serializers;
import java.lang.reflect.ParameterizedType;
abstract class XmlSerializableObject<T> {
abstract T getDefault();
abstract String getSerializedFilePath();
String getGenericName() {
return ((Class<T>) ((ParameterizedType) getClass()
.getGenericSuperclass()).getActualTypeArguments()[0]).getTypeName();
}
ClassLoader getClassLoader() {
return ((Class<T>) ((ParameterizedType) getClass()
.getGenericSuperclass()).getActualTypeArguments()[0]).getClassLoader();
}
}
getGenericName 和getClassLoader 用于实例化JAXBContext。然后我有一个基本的实现作为设置提供者
public class SettingsProvider extends XmlSerializableObject<SettingsProvider> {
private Settings settings;
@Override
public SettingsProvider getDefault() {
return null;
}
@Override
public String getSerializedFilePath() {
return "C:\\Data\\__tmp.settings";
}
public Settings getSettings() {
return settings;
};
public void setSettings(Settings settings) {
this.settings = settings;
}
}
class Settings {
private String tmp;
public String getTmp() {
return tmp;
}
public void setTmp(String tmp) {
this.tmp = tmp;
}
}
现在我有以下序列化程序类
package serializers;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.File;
public class XmlSerializer {
private static final Logger logger = LoggerFactory.getLogger(XmlSerializer.class);
public static <T extends XmlSerializableObject> void Serialize(T o) {
String filePath = o.getSerializedFilePath();
File file = new File(filePath);
try {
String name = o.getGenericName();
ClassLoader classLoader = o.getClassLoader();
// THE FOLLOWING LINE throws.
JAXBContext jaxbContext = JAXBContext.newInstance(name, classLoader); // also tried JAXBContext.newInstance(name);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
jaxbMarshaller.marshal(o, file);
} catch (JAXBException e) {
logger.error("Serialization failed", e);
}
}
// Deserialize below.
}
然后我有下面的测试来检查序列化的结果
package serializers;
import org.junit.Before;
import org.junit.Test;
public class XmlSerializerTest {
private Settings settings = new Settings();
private SettingsProvider provider;
@Before
public void setUp() throws Exception {
settings.setTmp("testing");
provider = new SettingsProvider();
provider.setSettings(settings);
}
@Test
public void serialize() throws Exception {
XmlSerializer.Serialize(provider);
}
}
问题是对JAXBContext jaxbContext = JAXBContext.newInstance(name, classLoader); 的调用引发了
javax.xml.bind.JAXBException:提供程序 com.sun.xml.internal.bind.v2.ContextFactory 无法实例化:javax.xml.bind.JAXBException:“serializers.SettingsProvider”不包含 ObjectFactory.class 或 jaxb 。指数 - 有关联的例外: [javax.xml.bind.JAXBException:“serializers.SettingsProvider”不包含 ObjectFactory.class 或 jaxb.index]
我尝试使用和不使用 ClassLoader 对象均无济于事。如何以这种方式序列化泛型类型?
感谢您的宝贵时间。
【问题讨论】:
标签: java serialization