为什么以及何时在JAXB中需要JAXBElement?
我只是在学习JAXB(用于XML绑定的Java体系结构)。 通过一些消息来源,我想到了JAXBElement
一个疑问。
Oracle文档说:
When XML element information can not be inferred by the derived Java representation of the XML content, a JAXBElement object is provided. This object has methods for getting and setting the object name and object value.
链接在这里
当Schema定义的数据类型和Java数据类型之间没有直接映射时,是否需要使用JAXBElement
?
此外,在下面列出的一个代码示例中。 我从这里跟随:
ObjectFactory factory = new ObjectFactory(); UserT user = factory.createUserT(); user.setUserName("Sanaulla"); ItemT item = factory.createItemT(); item.setItemName("Seagate External HDD"); item.setPurchasedOn("August 24, 2010"); item.setAmount(new BigDecimal("6776.5")); ItemListT itemList = factory.createItemListT(); itemList.getItem().add(item); ExpenseT expense = factory.createExpenseT();// we get expense object here expense.setUser(user); expense.setItems(itemList); JAXBContext context = JAXBContext.newInstance("generated"); JAXBElement element = factory.createExpenseReport(expense);//why is this required Marshaller marshaller = context.createMarshaller(); marshaller.setProperty("jaxb.formatted.output",Boolean.TRUE); marshaller.marshal(element,System.out);
使用ExpenseT expense = factory.createExpenseT();
我们能够获得ExpenseT
对象。
如果我们看到,我们再次在代码中创建
JAXBElement element = factory.createExpenseReport(expense);
根据这个来源是expense
对象的包装。
另一方面,我们不为使用检索的对象创建包装器
UserT user = factory.createUserT();
所以我的问题是:
-
JAXBElement
包装expense
需要什么? - 什么时候使用
JAXBElement
?
有一些用例需要JAXBElement
:
- 元素是
nillable="true"
和minOccurs="0"
。 在这种情况下,映射字段/属性上的null
是什么意思? 当属性为JAXBElement
,null值表示该元素不存在,JAXBElement
包装null表示具有xsi:nil="true"
的XML元素。 - 有两个全局元素具有相同的命名复杂类型。 由于在JAXB类中对应于复杂类型,因此需要一种方法来捕获遇到的根元素。
- 有一个选择结构,
foo
或bar
元素可以出现,它们是相同的类型。 这里需要JAXBElement
,因为仅仅遇到String
值不足以指示应该编组哪个元素。 - 在包含属性的文档中遇到具有
xsi:nil
的元素。 在此示例中,对应于该元素的对象仍然可以被解组以保存属性值,但JAXBElement可以指示该元素为null。
JAXBElement用于在对象模型中不存在足够信息的用例中保留元素名称/命名空间。 它经常与替代组一起使用。
如果没有任何JAXB元数据,结果将被包装在JAXBElement中。 您可以使用@XmlRootElement批注来消除根级别JAXBElement。
如果您使用来自外部源的xsd文件,并且在生成的类上没有可用的XmlRootElement注释,则在编组过程中使用JAXBElement可以真正派上用场,因为您可以使用JAXBElement包装器将xml解组为对象。 你会看到指定类本身在这种情况下不起作用……
这将有效:
JAXBElement
这将抛出一个JAXBException:
Object obj = (Object) unmarshaller.unmarshal(objectXML);