我有以下情况:
项目有一个通用的配置文件和一个特定的配置文件,我需要使用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实例。
任何人都可以帮助我吗?
非常感谢!