使用IBM的JAXB实现时解组子类的问题

时间:2013-06-18 10:44:55

标签: inheritance jaxb websphere subclass

我有以下情况:

项目有一个通用的配置文件和一个特定的配置文件,我需要使用jaxb unmarshalling创建特定配置文件的实例。

超类ConfigA.java:

package net.test;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "config")
@XmlAccessorType(XmlAccessType.FIELD)
public class ConfigA {

private String attribute1;

private String attribute2;

public String getAttribute1() {
    return attribute1;
}

public void setAttribute1(String attribute1) {
    this.attribute1 = attribute1;
}

public String getAttribute2() {
    return attribute2;
}

public void setAttribute2(String attribute2) {
    this.attribute2 = attribute2;
}

}

package net.test; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement(name = "config") @XmlAccessorType(XmlAccessType.FIELD) public class ConfigA { private String attribute1; private String attribute2; public String getAttribute1() { return attribute1; } public void setAttribute1(String attribute1) { this.attribute1 = attribute1; } public String getAttribute2() { return attribute2; } public void setAttribute2(String attribute2) { this.attribute2 = attribute2; } }

和子类ConfigB.java:

package net.test;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "config")
@XmlAccessorType(XmlAccessType.FIELD)
public class ConfigB extends ConfigA {

private String attribute3;

public String getAttribute3() {
    return attribute3;
}

public void setAttribute3(String attribute3) {
    this.attribute3 = attribute3;
}
}

相应的xml文件:

package net.test;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "config")
@XmlAccessorType(XmlAccessType.FIELD)
public class ConfigB extends ConfigA {

private String attribute3;

public String getAttribute3() {
    return attribute3;
}

public void setAttribute3(String attribute3) {
    this.attribute3 = attribute3;
}
}

工厂类是:

<config> <attribute1>a</attribute1> <attribute2>b</attribute2> <attribute3>c</attribute3> </config>

现在junit测试是:

package net.test;

import java.io.InputStream;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

public class ConfigFactory {

    public static <T extends ConfigA> T createConfig(String file, Class<T> clazz) {
        T config = null;

        JAXBContext context = null;
        Unmarshaller unmarshaller = null;

        try {
            file = "/" + file;
            InputStream stream = ConfigFactory.class.getResourceAsStream(file);
            if (stream == null) {
                // Error handling
            }
            if (clazz != null) {
                context = JAXBContext.newInstance(ConfigA.class, clazz);
            } else {
                context = JAXBContext.newInstance(ConfigA.class);
            }
            unmarshaller = context.createUnmarshaller();

            unmarshaller.setSchema(null); // No Schema
            config = (T)unmarshaller.unmarshal(stream);

        } catch (JAXBException e) {
            // exception handling
        } catch (Exception e) {
            // exception handling
        }
        return config;
    }
}

package net.test; import java.io.InputStream; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Unmarshaller; public class ConfigFactory { public static <T extends ConfigA> T createConfig(String file, Class<T> clazz) { T config = null; JAXBContext context = null; Unmarshaller unmarshaller = null; try { file = "/" + file; InputStream stream = ConfigFactory.class.getResourceAsStream(file); if (stream == null) { // Error handling } if (clazz != null) { context = JAXBContext.newInstance(ConfigA.class, clazz); } else { context = JAXBContext.newInstance(ConfigA.class); } unmarshaller = context.createUnmarshaller(); unmarshaller.setSchema(null); // No Schema config = (T)unmarshaller.unmarshal(stream); } catch (JAXBException e) { // exception handling } catch (Exception e) { // exception handling } return config; } }

这适用于Sun的jaxb参考实现:jaxb-impl-2.1.9.jar,但在Webshpere下,ConfigFactory.createConfig()方法始终只返回ConfigA的实例,而不是ConfigB。

在createConfig()方法中尝试了以下内容:

@Test
public void testConfig() throws Exception {
    ConfigB config = ConfigFactory.createConfig("config.xml", ConfigB.class);
    assertNotNull(config);
    assertEquals(config.getClass(), ConfigB.class);
}

@Test public void testConfig() throws Exception { ConfigB config = ConfigFactory.createConfig("config.xml", ConfigB.class); assertNotNull(config); assertEquals(config.getClass(), ConfigB.class); }

JAXBContext.newInstance(clazz, ConfigA.class);

使用这两个代码,即使使用jaxb参考实现也只创建ConfigA实例。

任何人都可以帮助我吗?

非常感谢!

0 个答案:

没有答案