我正在尝试编写一个类,使用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();
}
}
在使用JAXBContext
实例化时,getGenericName
和getClassLoader
可用。我已经编写了一个基本的实现作为设置提供程序。
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.index - 带有关联异常: [javax.xml.bind.JAXBException:"serializers.SettingsProvider"不包含ObjectFactory.class或jaxb.index]
ClassLoader
对象,但都没有成功。如何以这种方式序列化泛型类型?感谢您的时间。