0
我有以下问题:我有一些代码(我无法更改)父类的一个变量获取子类的变量的影子。当注释为@XmlAttribute
并用JAXB编组时,这会导致非法XML,并且在解组时会导致异常(由于非法XML)。这里是一个小例子,示出了该问题:JAXB中的非法XML /异常取消/编组阴影变量
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.helpers.DefaultValidationEventHandler;
import org.junit.Test;
public class InheritanceJaxbTest {
@Test
public void testInheritanceField() {
B b = new B("value");
String xml = toXML(b);
System.out.println(xml);
B b_out = fromXML(xml);
System.out.println(b_out.myField);
}
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
private static class A {
public A() {
}
public A(String myField) {
this.myField = myField;
}
@XmlAttribute
private String myField;
}
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
private static class B extends A {
public B() {
super();
}
public B(String myField) {
super(myField);
this.myField = myField;
}
@XmlAttribute
private String myField;
}
public <T> T fromXML(String xml) {
try {
JAXBContext jc = JAXBContext.newInstance(A.class, B.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
unmarshaller.setEventHandler(new DefaultValidationEventHandler());
return (T) unmarshaller.unmarshal(new ByteArrayInputStream(xml.getBytes()));
} catch (Exception exc) {
throw new RuntimeException(exc);
}
}
public String toXML(Object obj) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(baos);
JAXBContext jc = JAXBContext.newInstance(A.class, B.class);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
marshaller.setEventHandler(new DefaultValidationEventHandler());
marshaller.marshal(obj, ps);
return baos.toString();
} catch (Exception exc) {
throw new RuntimeException(exc);
}
}
}
这将产生以下(显然非法的)XML:
<b myField="value" myField="value"/>
而其后的解组操作引发以下例外:
java.lang.RuntimeException: javax.xml.bind.UnmarshalException
- with linked exception:
[org.xml.sax.SAXParseException: Attribute "myField" was already specified for element "b".]
at InheritanceJaxbTest.fromXML(InheritanceJaxbTest.java:67)
由于我基本上不能更改底层的Java类,我想用某种XmlAdapter或自定义的XmlStreamWriter或类似的东西来解决这个问题。有关如何进行的任何建议?
This question是相关的,但仍然没有见识如何继续而不改变Java类。
非常感谢,这似乎是一个非常有希望的方向去调查。我会这样做,让你知道结果:-) – roesslerj