教程的内容:
JAXB用于简单的Java-XML序列化
在Java中有很多方法可以做XML序列化。 如果您想对parsing和序列化进行细粒度的控制,则可以使用SAX,DOM或Stax来获得更好的性能。 然而,我经常想要做的是POJO和XML之间的简单映射。 但是,创buildJava类来手动执行XML事件parsing不是微不足道的。 我最近发现JAXB是一个快捷方便的Java-XML映射或序列化。
JAXB包含很多有用的function,您可以在这里查看参考实现。 Kohsuke的博客也是学习更多关于JAXB的好资源。 对于这个博客条目,我将向您展示如何使用JAXB进行简单的Java-XML序列化。
POJO到XML
比方说,我有一个项目的Java对象。 我想将一个Item对象序列化为XML格式。 我首先要做的就是用javax.xml.bind.annotation。*包中的一些XML注释来注释这个POJO。 请参阅Item.java的代码清单1
从代码
@XmlRootElement(name="Item")表示我想成为根元素。
@XmlType(propOrder = {"name", "price"})表示我希望元素在XML输出中排列的顺序。
@XmlAttribute(name="id", ...)表示id是根元素的一个属性。
@XmlElement(....)表示我想价格和名称是项目内的元素。
我的Item.java已经准备好了。 然后,我可以继续创build编组项目的JAXB脚本。
//creating Item data object Item item = new Item(); item.setId(2); item.setName("Foo"); item.setPrice(200); ..... JAXBContext context = JAXBContext.newInstance(item.getClass()); Marshaller marshaller = context.createMarshaller(); //I want to save the output file to item.xml marshaller.marshal(item, new FileWriter("item.xml"));
有关完整的代码清单,请参阅代码清单2 main.java 。 输出代码清单3的item.xml文件被创build。 它看起来像这样:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> Foo200
容易吗? 您可以通过简单地更改marshal(…)方法的参数来将输出XML作为文本String,Stream,Writer,ContentHandler等进行传送
... JAXBContext context = JAXBContext.newInstance(item.getClass()); Marshaller marshaller = context.createMarshaller(); // save xml output to the OutputStream instance marshaller.marshal(item, ); ... JAXBContext context = JAXBContext.newInstance(item.getClass()); Marshaller marshaller = context.createMarshaller(); StringWriter sw = new StringWriter(); //save to StringWriter, you can then call sw.toString() to get java.lang.String marshaller.marshal(item, sw);
XML到POJO
让我们改变过程。 假设我现在有一段XMLstring数据,我想把它变成Item.java对象。 XML数据(代码清单3)看起来像
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> Bar80
然后,我可以解组这个xml代码到Item对象
... ByteArrayInputStream xmlContentBytes = new ByteArrayInputStream (xmlContent.getBytes()); JAXBContext context = JAXBContext.newInstance(Item.getClass()); Unmarshaller unmarshaller = context.createUnmarshaller(); //note: setting schema to null will turn validator off unmarshaller.setSchema(null); Object xmlObject = Item.getClass().cast(unmarshaller.unmarshal(xmlContentBytes)); return xmlObject; ...
有关完整的代码清单,请参阅代码清单2(main.java)。 XML源可以来自Stream和文件的多种forms。 唯一的区别就是方法参数:
... unmarshaller.unmarshal(new File("Item.xml")); // reading from file ... // inputStream is an instance of java.io.InputStream, reading from stream unmarshaller.unmarshal(inputStream);
使用XML模式validation
我想提到的最后一件事是在解组到Java对象之前使用模式validationinputXML。 我创build了一个名为item.xsd的XML模式文件。 有关完整的代码清单,请参阅代码清单4(Item.xsd)。 现在我要做的就是注册这个模式进行validation。
... Schema schema = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI) .newSchema(new File("Item.xsd")); unmarshaller.setSchema(schema); //register item.xsd shcema for validation ...
当我尝试将XML数据解组为POJO时,如果input的XML不符合该模式,则将捕获exception。 有关完整的代码清单,请参阅代码清单5(invalid_item.xml)。
javax.xml.bind.UnmarshalException - with linked exception: javax.xml.bind.JAXBException caught: null [org.xml.sax.SAXParseException: cvc-datatype-valid.1.2.1: 'item1' is not a valid value for 'integer'.]
在这里,我将“id”属性更改为string而不是整数。
如果XMLinput对模式有效,则XML数据将成功解组到Item.java对象。