我遇到了一个有趣的JAXB问题让我困惑了一段时间,因为没有产生错误,只是没有看到我预期的输出。
我们有几个类都扩展了Base类。 有一次,我将一个对象属性引入基类,这也恰好是在一个子类中定义的属性。这导致任何子类(在具有该属性被覆盖的子类之外)的任何此属性的setter都在XML输出中完全忽略此属性。
例如:
@XmlRootElement(name = "animal")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlSeeAlso({Dog.class, Fish.class})
public class Animal {
protected String movement;
....
}
@XmlRootElement(name = "dog")
@XmlSeeAlso({Animal.class})
@XmlAccessorType(XmlAccessType.FIELD)
public class Dog extends Animal {
private String breed;
protected String movement;
....
}
@XmlRootElement(name = "fish")
@XmlSeeAlso({Animal.class})
@XmlAccessorType(XmlAccessType.FIELD)
public class Fish extends Animal {
private String scaleType;
....
}
public static void main(String[] args) {
Dog dog = new Dog();
dog.setBreed("lab");
dog.setMovement("walks");
String xml = AnimalJaxb.toXml(dog);
System.out.println("dog = "+xml);
Fish fish = new Fish();
fish.setMovement("swims"); //WILL NOT SHOW UP IN XML!
fish.setScaleType("normal");
String xml = AnimalJaxb.toXml(fish);
System.out.println("fish = "+xml);
//to and from XML looks like...
public static <T> T fromXml(String xml, Class<T> clazz) throws Exception {
ByteArrayInputStream input = null;
Unmarshaller u = null;
try {
input = new ByteArrayInputStream(xml.getBytes());
JAXBContext jc = JAXBContext.newInstance(clazz);
u = jc.createUnmarshaller();
} catch (Exception e) {
throw e;
} finally {
input.close();
}
return (T) u.unmarshal(input);
}
public static String toXml(Object obj) throws Exception {
StringWriter sw = new StringWriter();
try {
JAXBContext context = JAXBContext.newInstance(obj.getClass());
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
m.marshal(obj, sw);
return sw.toString();
} catch (Exception e) {
throw e;
} finally {
sw.close();
}
}
当上述运行时。 &#34;运动&#34; Fish上的属性不会出现在XML中。要解决这个问题,我需要删除Dog类中重写的移动属性。
令人沮丧的是JAXB没有抛出任何错误或抱怨。抱怨的唯一方法是,如果我将基类(Animal)抽象化并将其标记为@XmlTransient,之后JAXB会抱怨有两个具有相同名称的属性。&#34;