JAXB使用教程


声明:本文转载自https://my.oschina.net/u/3300985/blog/1612655,转载目的在于传递更多信息,仅供学习交流之用。如有侵权行为,请联系我,我会及时删除。

JAXB教程

Java为处理XML文件和结构提供了多种选择,目前应用最为广泛的是JAXB工具库。JAXB代表了Java处理XML文件的事实上标准,它提供了Java对象与XML文本之间互相转换的功能。从JRE6开始,JAXB就已经成为了JRE的内置模块。

在JAXB之前,Java处理XML的方式只能是使用DOM解析,而采用这种方式并不是一个最优的解决方案,因为DOM解析几乎不能将XML与Java对象映射起来,所有的值类型都只能映射为String字符串。JAXB为XML节点和属性提供了各种面向对象的处理方式,可以基于自定义类型、注解等方式将XML转换成Java对象。

映射

Java对象可以通过特定的注解或者依照规范被转换为XML,这种转换成为映射(mapping)。本教程将通过案例向读者介绍以下内容:

  • 通过案例的方式展示如何将Java对象转换为XML,这被称之为marshaling,我将展示如何处理原始数据类型、集合和使用适配器(adapter)来处理更加复杂的类型。
  • 通过案例展示如何将XML转换为Java对象,这被称为un-marshaling。
  • 详细介绍JAXB注解的作用
  • 提供对XSDs(XML Schemas)的介绍,XSDs用于验证XML,这是JAXB提供的一项高级功能
  • 最后,我将介绍几个通过JAXB处理XML的有用的工具。

Marshal

本部分将介绍如何将Java对象转换为XML以及转换过程中的注意事项,这项操作被称之为Marshaling. 首先,我们将业务对象的中的Java域与XML中的元素做一一对应。

@XmlType( propOrder = { "name", "capital", "foundation", "continent" , "population"} ) @XmlRootElement( name = "Country" ) public class Country {     @XmlElement (name = "Country_Population")     public void setPopulation( int population )     {         this.population = population;     }     @XmlElement( name = "Country_Name" )     public void setName( String name )     {         this.name = name;     }     @XmlElement( name = "Country_Capital" )     public void setCapital( String capital )     {         this.capital = capital;     }     @XmlAttribute( name = "importance", required = true )     public void setImportance( int importance )     {         this.importance = importance;     } ... 

这个类中包含了几个注解,这些注解明确指出了我们将会创建哪些XML节点。

  • @XmlRootElement 表示root元素
  • @XmlElement与setter方法结合使用
  • @XmlAttribute用于为XML节点添加属性。这些属性可以通过设置required的值来表示是否为必备的。
  • @XmlType用于明确指示XML元素的排列顺序。

那么,如何将具体的Java对象转换为XML呢?对此,我们可以创建一个JAXBContext并使用其marshal方法来做个demo。

Country spain = new Country(); spain.setName( "Spain" ); spain.setCapital( "Madrid" ); spain.setContinent( "Europe" ); spain.setImportance( 1 ); spain.setFoundation( LocalDate.of( 1469, 10, 19 ) ); spain.setPopulation( 45000000 ); /* init jaxb marshaler */ JAXBContext jaxbContext = JAXBContext.newInstance( Country.class ); Marshaller jaxbMarshaller = jaxbContext.createMarshaller(); /* set this flag to true to format the output */ jaxbMarshaller.setProperty( Marshaller.JAXB_FORMATTED_OUTPUT, true ); /* marshaling of java objects in xml (output to file and standard output) */ jaxbMarshaller.marshal( spain, new File( "country.xml" ) ); jaxbMarshaller.marshal( spain, System.out ); 

基本上来说,这个例子的核心就是JAXBContext,JAXBContext提供了marshal、unmarshal的方法,是我们使用JAXB API的入口。 在我们的例子中,我们提供为JAXBContext实例提供了需要marshal的类,通过以下代码实现:

JAXBContext jaxbContext = JAXBContext.newInstance( Country.class ); Marshaller jaxbMarshaller = jaxbContext.createMarshaller(); 

以上例子的输出结果应该是这样的:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <Country importance="1">  <Country_Name>Spain</Country_Name>  <Country_Capital>Madrid</Country_Capital>  <Country_Foundation_Date></Country_Foundation_Date>  <Country_Continent>Europe</Country_Continent>  <Country_Population>45000000</Country_Population> </Country> 

上面这个例子我们实现了基本数据类型转换为XML的功能,Fundation_Date元素是空的,我们接下来会介绍如何解决这个问题。

看上去并不难,JAXB提供了将各种Java对象转换为XML的方法,比如将一个List的country转换为XML:

@XmlRootElement( name = "Countries" ) public class Countries {     List countries;     /**      * element that is going to be marshaled in the xml      */      @XmlElement( name = "Country" )     public void setCountries( List countries )     {         this.countries = countries;     } } 

通过设置一个List来把集合转换为XML。该例子的输出结果为:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <Countries>         <Country importance="1">                 <Country_Name>Spain</Country_Name>                 <Country_Capital>Madrid</Country_Capital>                 <Country_Foundation_Date></Country_Foundation_Date>                 <Country_Continent>Europe</Country_Continent>                 <Country_Population>0</Country_Population>         </Country>         <Country importance="0">                 <Country_Name>USA</Country_Name>                 <Country_Capital>Washington</Country_Capital>                 <Country_Foundation_Date></Country_Foundation_Date>                 <Country_Continent>America</Country_Continent>                 <Country_Population>0</Country_Population>         </Country> </Countries> 

处理集合框架的方式有好几种:

  1. 使用wrapper注解,javax.xml.bind.annotation.XMLElementWrapper注解提供了一种XML包装器,这个包装器可以放置Java集合。
  2. 可以使用javax.xml.bind.annotation.XMLElements或者javax.xml.bind.annotation.XMLRefs等表示Java集合的注解,但是这种方式缺乏灵活性。
  3. 对集合使用容器类,这也是我们这里展示的例子所使用的方法。通过将集合设置为内部类的域,实现Java集合的Marshal。

Un-marshal

这一小节将介绍上一节的逆操作——将XML解析为Java对象。 假设以下XML是我们要解析的文本:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <Countries>         <Country>                 <Country_Name>Spain</Country_Name>                 <Country_Capital>Madrid</Country_Capital>                 <Country_Continent>Europe</Country_Continent>         </Country>         <Country>                 <Country_Name>USA</Country_Name>                 <Country_Capital>Washington</Country_Capital>                 <Country_Continent>America</Country_Continent>         </Country>         <Country>                 <Country_Name>Japan</Country_Name>                 <Country_Capital>Tokyo</Country_Capital>                 <Country_Continent>Asia</Country_Continent>         </Country> </Countries> 

接下来创建一个程序来读取这个XML的内容并解析为Java对象:

File file = new File( "countries.xml" ); JAXBContext jaxbContext = JAXBContext.newInstance( Countries.class ); /** * the only difference with the marshaling operation is here */ Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); Countries countres = (Countries)jaxbUnmarshaller.unmarshal( file ); System.out.println( countres ); 

以上的代码与上一章提供的Java转为XML的代码并没有太多的不同。通过JAXBContent创建一个Unmarshaller对象,将XML直接转换为Java对象。 这个例子中使用到了Country类,其代码如下:

@XmlType( propOrder = { "name", "capital", "foundation", "continent" , "population"} ) @XmlRootElement( name = "Country" ) public class Country {     @XmlElement (name = "Country_Population")     public void setPopulation( int population )     {         this.population = population;     }     @XmlElement( name = "Country_Name" )     public void setName( String name )     {         this.name = name;     }     @XmlElement( name = "Country_Capital" )     public void setCapital( String capital )     {         this.capital = capital;     }     @XmlAttribute( name = "importance", required = true )     public void setImportance( int importance )     {         this.importance = importance;     } ... 

与上一章节中的Country类是一模一样的。 以上Java代码的输出结果如下:

Name: Spain Capital: Madrid Europe Name: USA Capital: Washington America Name: Japan Capital: Tokyo Asia 

同理,我们可以使用相同的方式Unmarshalling其他的原始数据类型或者集合类型。

适配器(Adapters)

处理无法直接使用的复杂数据类型的解析和映射时,我们需要使用适配器的方式来告诉JAXB如何处理这些特定的类型。这里简单通过解析和映射java.time.LocalDate的例子来展示JAXB在处理复杂数据类型上的强大功能。

public class DateAdapter extends XmlAdapter{     public LocalDate unmarshal( String date ) throws Exception     {         return LocalDate.parse( date );     }     public String marshal( LocalDate date ) throws Exception     {        return date.toString();     } }  

以上代码展示了如何通过javax.xml.bind. annotation.adapters.XmlAdapter对特定的类型进行marshal和unmarshal,在Java代码中通过以下代码做映射:

@XmlElement( name = "Country_Foundation_Date" ) @XmlJavaTypeAdapter( DateAdapter.class ) public void setFoundation( LocalDate foundation ) {     this.foundation = foundation; } 

运行的结果:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <Country importance="1">         <Country_Name>Spain</Country_Name>         <Country_Capital>Madrid</Country_Capital>         <Country_Foundation_Date>1469-10-19</Country_Foundation_Date>         <Country_Continent>Europe</Country_Continent>         <Country_Population>45000000</Country_Population> </Country> 

通过这种方式,我们可以将复杂的类型映射为XML,我们只需要实现XmlAdapter接口,并复写其中的marshal和unmarshal方法即可达到目的。

注解

本文发表于2018年01月25日 10:32
(c)注:本文转载自https://my.oschina.net/u/3300985/blog/1612655,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如有侵权行为,请联系我们,我们会及时删除.

阅读 1877 讨论 0 喜欢 0

抢先体验

扫码体验
趣味小程序
文字表情生成器

闪念胶囊

你要过得好哇,这样我才能恨你啊,你要是过得不好,我都不知道该恨你还是拥抱你啊。

直抵黄龙府,与诸君痛饮尔。

那时陪伴我的人啊,你们如今在何方。

不出意外的话,我们再也不会见了,祝你前程似锦。

这世界真好,吃野东西也要留出这条命来看看

快捷链接
网站地图
提交友链
Copyright © 2016 - 2021 Cion.
All Rights Reserved.
京ICP备2021004668号-1