如何使JAXB识别不同的类

时间:2015-01-30 13:41:53

标签: java xml jaxb

我已经实现了JAXB将XML数据转换为Object,这里我就像这样使用了。

假设新用户已注册。所以我要在适当的类中加载数据以将其存储在DB中。所以我用硬编码为.newInstance(User.Class)

JAXBContext context = JAXBContext.newInstance(User.class);

现在我要做一些与雇主相关的功能。 为此我需要将它作为.newInstance(Employer.class)。可以通过复制粘贴相同的jaxb转换并用.newInstance(Employer.Class)替换.newInstance(User.Class)。但是我希望将JAXB转换为Util,它可以用于不同的类而不会破坏相应的类

我有像这样的XML数据

<User>
    <username>user</username>
    <password>password</password>
</User>

我试图做的是,如果我要从UserController调用JaxbUtil.java,我会将其存储为

String className = "User.class";

如果我从EmployerComtroller调用它

String className = "Employer.class";

然后在调用方法时,它就像

JaxbUtil.jaxbXMLToObject(xmlData,className);

这是我在JaxbUtil.java中的jaxbXMLToObject方法

public static User jaxbXMLToObject(String xmlData,String className) {   //I've passed the xmlString to unmarshaller by StringReader
    User user = null;
    JAXBContext context = JAXBContext.newInstance(className);
    return user; // Ofcourse this is after conversion 
}

现在我希望你们能理解我想说的话。

1).newInstance()不接受String

2)即使我让它识别(不可能,只是假设),我也要在方法声明中更改返回类型。

是否可以将此方法用于所有xml到不同的Object转换,而无需为每个Object创建单独的方法?

解决方案:

String xmlData; // Assume I've xmlData stored as String
Class<?> classType = Class.forName("com.package.model.Employer");
Employer employer = (Employer) JAXBUtil.jaxbXMLToObject(xmlData,classType);    //JaxbUtil is the Util class where the below code is saved

public static Object jaxbXMLToObject(String xmlData, Class<?> classType) throws ClassNotFoundException {
Object object = null;
    try {

        JAXBContext context = JAXBContext.newInstance(classType);
        Unmarshaller unmarshaller = context.createUnmarshaller();
        StringReader reader = new StringReader(xmlData);
        object = (Object) unmarshaller.unmarshal(reader);
    } catch (JAXBException e) {
        e.printStackTrace();
    }
    return object;
}

所以我现在可以通过更改每个控制器中的类名来调用Util方法。

编辑: 接受的答案比上面发布的解决方案标准化得多。如果你要实施它,请参考接受的答案。

2 个答案:

答案 0 :(得分:1)

您需要使用ClassLoader从类名加载真实类。然后在该类上引导JAXBContext


更新

  

如何使返回类型通用?我的意思是,每个班级都独立   彼此之间,像用户操作必须返回用户,雇主   操作必须返回雇主,但用户和雇主都不是   有接口或扩展关系

如果您可以将参数设为Class而不是String,那么您可以执行以下操作。 jaxbXMLToObject的返回类型将是您传入的类型。

public static <T> T jaxbXMLToObject(String xmlData, Class<T> clazz) {   //I've passed the xmlString to unmarshaller by StringReader
    try {
        T result = null;
        JAXBContext context = JAXBContext.newInstance(clazz);

        Unmarshaller unmarshaller = context.createUnmarshaller();
        StreamSource source = new StreamSource(new StringReader(xmlData));
        result = unmarshaller.unmarshal(source, clazz).getValue();
        return result; // Ofcourse this is after conversion 
    } catch(JAXBException e) {
        // TODO - Handle Exception
    }
    return null;
}

然后您将能够执行以下操作:

Foo foo = jaxbXMLToObject(xmlData, Foo.class);
Bar bar = jaxbXMLToObject(xmlData, Bar.class);

答案 1 :(得分:0)

两个可能的答案:

  • 如果要从xml解组到对象,则需要创建 对象要解组,这就是重点。

  • 如果要将xml文件放在字符串中,则不需要JAXB。