我用JAXB来读写XML。我要的是一个基类JAXB的编组和继承的JAXB类解组。这是为了允许一个发送者的Java应用程序发送XML到另一个接收机的Java应用程序。发送者和接收者将共享JAXB库。我想接收到的XML解组到它扩展了通用的JAXB类接收器特定的JAXB类。 例如: 这是JAXB类,它由发送方。
-------------------------------------------------------------------------------------------------------------------------
1. 你是JAXB 2.0吧? (因为JDK6) 还有一类:
2. 下面的代码片断是一个JUnit 4测试了绿灯:
3. 子人两次,一次为接收器和一次发送者,只有把这些subclassses(离开超 CodeGo.net,
4. 创建一个自定义的ObjectFactory解组期间实例化所需的类。例如:
5. 我不知道你为什么会想这样做...它似乎所有的安全并 考虑ReceiverPerson会发生什么事情有更多的实例变量...那么你会风与(我猜的)这些变量为null,0或false ...而如果空不允许或数必须大于0? 我想你可能想要做的是读取联系人,然后从构造一个新的ReceiverPerson(可能会提供一个构造函数接受一个Person)。
@XmlRootElement(name="person")
public class Person {
public String name;
public int age;
}
这是接收特定的JAXB解组XML时。接收器类具有特定于接收机中的应用逻辑。
@XmlRootElement(name="person")
public class ReceiverPerson extends Person {
public doReceiverSpecificStuff() ...
}
编组如预期般运作。问题是解组,它仍然要解组
Person
尽管子类的包
ReceiverPerson
。
JAXBContext jaxbContext = JAXBContext.newInstance(package name of ReceiverPerson);
我想要的是来解读为
ReceiverPerson
。我已经能够做到这一点的唯一方法是删除
@XmlRootElement
从
Person
。不幸的是这样做防止
Person
被封。这是因为如果JAXB开始于基类和它的工作方式,直到它找到优先个
@XmlRootElement
用适当的我试过添加
createPerson()
方法,它返回
ReceiverPerson
至
ObjectFactory
但是这并没有帮助。
-------------------------------------------------------------------------------------------------------------------------
1. 你是JAXB 2.0吧? (因为JDK6) 还有一类:
javax.xml.bind.annotation.adapters.XmlAdapter<ValueType,BoundType>
哪一个可以继承和覆盖
public abstract BoundType unmarshal(ValueType v) throws Exception;
public abstract ValueType marshal(BoundType v) throws Exception;
例如:
public class YourNiceAdapter
extends XmlAdapter<ReceiverPerson,Person>{
@Override public Person unmarshal(ReceiverPerson v){
return v;
}
@Override public ReceiverPerson marshal(Person v){
return new ReceiverPerson(v); // you must provide such c-tor
}
}
用法做了如下:
@Your_favorite_JAXB_Annotations_Go_Here
class SomeClass{
@XmlJavaTypeAdapter(YourNiceAdapter.class)
Person hello; // field to unmarshal
}
我敢肯定,这个概念你可以自己控制编组/解组过程(包括选择正确的[子|超]类型构造)。
2. 下面的代码片断是一个JUnit 4测试了绿灯:
@Test
public void testUnmarshallFromParentToChild() throws JAXBException {
Person person = new Person();
int age = 30;
String name = "Foo";
person.name = name;
person.age= age;
// Marshalling
JAXBContext context = JAXBContext.newInstance(person.getClass());
Marshaller marshaller = context.createMarshaller();
StringWriter writer = new StringWriter();
marshaller.marshal(person, writer);
String outString = writer.toString();
assertTrue(outString.contains("</person"));
// Unmarshalling
context = JAXBContext.newInstance(Person.class, RecieverPerson.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
StringReader reader = new StringReader(outString);
RecieverPerson reciever = (RecieverPerson)unmarshaller.unmarshal(reader);
assertEquals(name, reciever.name);
assertEquals(age, reciever.age);
}
最重要的部分是的
JAXBContext.newInstance(Class... classesToBeBound)
方法对数据编出上下文:
context = JAXBContext.newInstance(Person.class, RecieverPerson.class);
通过此调用,JAXB上指定的类的引用封闭,并将确认
RecieverPerson
。该测试通过。如果你改变了顺序,你会得到一个
java.lang.ClassCastException
(所以他们必须在这个顺序传递)。
3. 子人两次,一次为接收器和一次发送者,只有把这些subclassses(离开超 CodeGo.net,
Person
,没有注意,发送者和接收者双方共享的JAXB基类。
@XmlRootElement(name="person")
public class ReceiverPerson extends Person {
// receiver specific code
}
@XmlRootElement(name="person")
public class SenderPerson extends Person {
// sender specific code (if any)
}
// note: no @XmlRootElement here
public class Person {
// data model + jaxb annotations here
}
[测试,并使用JAXB工作。它绕过你注意到这个问题,当多个类继承层次结构有注释。 这也可以说是一个整洁,更面向对象的方法,它分离了数据模型,所以它不是一个“解决方法”的说法。
4. 创建一个自定义的ObjectFactory解组期间实例化所需的类。例如:
JAXBContext context = JAXBContext.newInstance("com.whatever.mypackage");
Unmarshaller unmarshaller = context.createUnmarshaller();
unmarshaller.setProperty("com.sun.xml.internal.bind.ObjectFactory", new ReceiverPersonObjectFactory());
return unmarshaller;
public class ReceiverPersonObjectFactory extends ObjectFactory {
public Person createPerson() {
return new ReceiverPerson();
}
}
5. 我不知道你为什么会想这样做...它似乎所有的安全并 考虑ReceiverPerson会发生什么事情有更多的实例变量...那么你会风与(我猜的)这些变量为null,0或false ...而如果空不允许或数必须大于0? 我想你可能想要做的是读取联系人,然后从构造一个新的ReceiverPerson(可能会提供一个构造函数接受一个Person)。
6. 既然你真的有两个独立的应用程序,他们编译不同版本的类的“人”-与不具有接收器的应用程序@XmlRootElement(name="person")
上Person
。这不仅是丑陋的,但它违背了你想要的人的定义为发送者和接收者的可维护性。它的一个可取之处是,它的工作原理。
转载地址:http://codego.net/36754/