猿问

通用类的 JAXB 序列化失败

我正在尝试编写一个可以使用 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;


问题是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对象都无济于事。如何以这种方式序列化泛型类型?


谢谢你的时间。


千万里不及你
浏览 253回答 3
3回答

大话西游666

看起来应该是这样JAXBContext.newInstance(SettingsProvider.class)。该JAXBContext.newInstance(String ...)方法的版本需要一个包名,正如错误消息所说,它应该包含一个ObjectFactory类,或jaxb.index将其引导到类的列表。

茅侃侃

您正在使用此newInstance方法:参数:contextPath -包含模式派生类和/或 java 到模式(JAXB 注释)映射类的java 包名称列表classLoader - 该类加载器将用于定位实现类。所以 df778899 是对的,你不应该使用这个签名作为getGenericName返回一个完全限定的类名而不是一个包。即使是包裹,您仍然会错过ObjectFactory.class或jaxb.index但JAXBContext.newInstance(SettingsProvider.class)也不会奏效。你会得到一个缺少的MarshalException指示@XmlRootElementSettingsProvider像这样注释:@XmlRootElement(name = "root")static class SettingsProvider extends XmlSerializableObject<SettingsProvider>{&nbsp; &nbsp; private Settings settings;&nbsp; &nbsp; // [...]最后你会得到:<?xml version="1.0" encoding="UTF-8" standalone="yes"?><root>&nbsp; &nbsp; <settings>&nbsp; &nbsp; &nbsp; &nbsp; <tmp>testing</tmp>&nbsp; &nbsp; </settings></root>
随时随地看视频慕课网APP

相关分类

Java
我要回答