![jaxb](https://i-blog.csdnimg.cn/blog_migrate/a17e258dbe769a3500db54489f829ceb.png)
jaxb
在本文中,我们提供了一个全面的Java XML绑定JAXB教程。 Java提供了几种用于处理XML结构和文件的选项。 JAXB是最常用和最常用的一种。 JAXB代表用于XML绑定的Java体系结构。 它提供了将Java对象转换为XML结构以及其他方法的可能性。 自JRE 1.6的第一个版本以来,JAXB附带了JRE标准包。
JAXB的第一个规范于2003年3月完成,其工作过程在Java Specification Request 31中进行了跟踪: https : //jcp.org/en/jsr/detail?id= 31。 在此规范要求中,您可以找到许多有关JAXB的使用寿命以及所做的所有改进的信息。
如前所述,自1.6版更新以来,JAX包中已包含JAXB。
在此之前,有必要将它们的库包含在特定的Java项目中才能使用它。
在JAXB可用之前(很久以前),Java处理XML文档的方式就是DOM: http : //www.w3.org/DOM/ 。 这不是一个很好的方法,因为几乎没有从XML节点到Java对象的抽象,并且所有值类型都被推断为字符串。 JAXB提供了许多好处,例如与XML节点和属性有关的面向对象方法,类型化的值,注释以及我们将在本文中解释的其他好处。
本教程中的所有示例均已使用以下软件版本实现:用于32b的JRE 1.8.0。 使用的IDE是Eclipse SDK版本:Luna(4.4)。 但是,任何其他包含JAXB API和IDE的Java版本都可以正常工作,因为所有代码都是标准的Java 8。
1.映射
可以通过使用某些注释和遵循特定规则将Java对象绑定到XML结构。 这就是我们所谓的映射。 在本教程中,我们将解释以下几点,提供示例,资源和其他信息:
- 我们将展示一些有关如何将Java对象转换为XML结构的示例,这称为封送处理。 我们将展示如何使用适配器处理基本类型,集合和更复杂的类型。
- 我们还将解释如何执行补充操作,称为非编组,即将XML文件转换为Java对象。
- 所有这些操作都是使用Java注释完成的,我们将列出并解释JAXB中使用的最重要的注释。
- 我们还将提供用于验证的XSD(XML模式)的介绍,这是JAXB支持的功能强大的工具。 我们还将看到XSD也可以用于编组。
- 最后,我们将列出几种可以与JAXB结合使用的工具,这些工具可以以不同的方式帮助程序员。
2.元帅
在本章中,我们将了解如何将Java对象转换为XML文件,以及在执行此操作时应考虑的因素。 这通常称为封送处理。
首先,我们向JAXB指出业务模型中的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;
}
...
上面的类包含一些JAXB注释,这些注释使我们能够指示要生成的XML节点。 为此,我们使用注释
@XmlRootElement
作为根元素。-
@XmlElement
与setter方法结合使用。 -
@XmlAttribute
将属性传递到XML节点。 这些属性可以具有是否需要的属性。 -
@XmlType
表示特殊选项,例如XML中的出现顺序。
在下一章中,我们将更详细地解释这些注释和其他注释。 目前,我只想在这里提及它们。
下一步是从Java对象生成XML文件。 为此,我们使用JAXBContext
及其封送功能创建一个简单的测试程序:
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 );
基本上,这里最重要的部分是使用类javax.xml.bind.JAXBContext
。 此类提供了一个框架,用于验证XML到Java对象中以及从Java对象中对XML进行编组和取消编组,它是JAXB API的入口点。 可以在以下位置找到有关此类的更多信息: https : //docs.oracle.com/javase/7/docs/api/javax/xml/bind/JAXBContext.html 。
在我们的小示例中,我们只是使用此类来创建JAXB上下文,该上下文允许我们封送作为参数传递的类型的对象。 正是在这里完成的:
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>
在上面显示的JAXB应用程序中,我们只是将容器类中存在的简单类型(字符串和整数)转换为XML节点。 例如,我们可以看到缺少基于日期的属性(如基础日期),稍后我们将说明如何解决复杂类型的问题。
这看起来很简单。 JAXB支持各种Java对象,例如其他原始类型,集合,日期范围等。
如果我们想将元素列表映射到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;
}
我们可以在上面的代码段中看到需要一个新的容器类,以指示JAXB存在包含列表的类。 与上面显示的程序类似的结果是:
<?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>
处理集合时有几种选择:
- 我们可以使用包装器注释:注释
javax.xml.bind.annotation.XMLElementWrapper
提供了围绕XML表示形式创建包装器的可能性。 该包装器可以包含元素的集合。 - 我们可以使用基于集合的注释,例如
javax.xml.bind.annotation.XMLElements
或javax.xml.bind.annotation.XMLRefs
,它们提供集合功能但灵活性较低。 - 我们可以使用容器进行收集。 一种容器类(
Countries
其具有类型的成员在我们的例子)java.util.Collection
(Country
在我们的例子)。 这是我最喜欢的方法,因为它提供了更大的灵活性。 这是之前显示的方法。
3.取消编组
在本章中,我们将看到如何执行补充操作:将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>
值得一提的是,我们删除了成立日期。 如果存在这些,由于JAXB不知道如何解组它们,我们将得到一个错误。 以后我们将看到如何解决这个问题。
之后,我们可以创建一个程序来“读取”该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 );
我们可以看到,上面的代码与上一章中有关编组操作的代码相差无几。 我们还使用类javax.xml.bind.JAXBContext
但是在这种情况下,使用的方法是createUnmarshaller()一个,它负责提供类型为javax.xml.bind.Unmarshaller
的对象。 此对象负责随后解组XML。
该程序使用带注释的类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;
}
...
我们不能理解与上一章中使用的类有太多差异,使用了相同的批注。
这是程序在标准控制台中产生的输出:
Name: Spain
Capital: Madrid
Europe
Name: USA
Capital: Washington
America
Name: Japan
Capital: Tokyo
Asia
此处适用于编组操作的解释说明。 可以取消编组对象或其他原始类型,例如数字对象。 也可以取消对诸如列表或集合之类的基于集合的元素进行编组,并且可能性是相同的。
正如我们在上一章和上一章中提供的结果中所看到的,类型java.time.LocalDate
的属性尚未转换。 发生这种情况是因为JAXB不知道该怎么做。 也可以使用适配器来处理像这样的复杂类型。 我们将在下一章中看到。
4.适配器
当处理JAXB中可能不直接可用的复杂类型时,我们需要编写一个适配器来指示JAXB如何管理特定类型。
我们将通过对java.time.LocalDate
类型的元素使用封送处理(和取消封送处理)的示例进行说明。
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
的编组和解编方法的实现,以及正确的类型和结果,然后,我们使用注解@XmlJavaTypeAdapter
指示JAXB在哪里使用它@XmlJavaTypeAdapter
:
...
@XmlElement( name = "Country_Foundation_Date" )
@XmlJavaTypeAdapter( DateAdapter.class )
public void setFoundation( LocalDate foundation )
{
this.foundation = foundation;
}
...
本教程中显示的第一个程序的结果XML将类似于:
<?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结构中没有JAXB直接支持的任何其他复杂类型。 我们只需要实现接口javax.xml.bind.annotation.adapters.XmlAdapter
并实现其方法javax.xml.bind.annotation.adapters.XmlAdapter.unmarshal(ValueType)
和javax.xml.bind.annotation.adapters.XmlAdapter.marshal(BoundType)
。
5. XSD
XSD是XML模式。 它包含有关XML文件和结构的信息以及应遵循的规则和约束。 这些规则可以应用于XML的结构,也可以应用于内容。 可以将规则连接起来,并可以使用所有类型的结构创建非常复杂的规则,在本文中,我们将展示有关如何使用XSD进行验证和编组的主要概念。
这是可用于本教程中的Country
类的XML Schema的示例:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Country">
<xs:complexType>
<xs:sequence>
<xs:element name="Country_Name" type="xs:string" />
<xs:element name="Country_Capital" type="xs:string" />
<xs:element name="Country_Foundation_Date" type="xs:string" />
<xs:element name="Country_Continent" type="xs:string" />
<xs:element name="Country_Population" type="xs:integer" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
使用XSD进行验证
XSD可以用于XML验证。 JAXB使用XSD来验证XML并确保对象和XML结构遵循预期的规则集。 为了针对XSD验证对象,我们需要首先创建XSD,例如:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:simpleType name="continentType">
<xs:restriction base="xs:string">
<xs:pattern value="Asia|Europe|America|Africa|Oceania"/>
</xs:restriction>
</xs:simpleType>
<xs:element name="Country">
<xs:complexType>
<xs:sequence>
<xs:element name="Country_Name" type="xs:string" minOccurs='1' />
<xs:element name="Country_Capital" type="xs:string" minOccurs='1' />
<xs:element name="Country_Foundation_Date" type="xs:string" minOccurs='1' />
<xs:element name="Country_Continent" type="continentType" minOccurs='1' />
<xs:element name="Country_Population" type="xs:integer" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
我们可以在程序中使用它来指示JAXB,我们希望在代码中使用什么XSD。 我们可以通过创建类javax.xml.validation.Schema
的实例并通过以下方式初始化其验证来做到这一点:
/**
* schema is created
*/
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI );
Schema schema = sf.newSchema( new File( "countries_validation.xsd" ) );
验证需要一个可以处理错误的错误处理程序。 这是通过实现org.xml.sax.ErrorHandler
接口及其错误方法来完成的:
public class MyErrorHandler implements ErrorHandler
{
@Override
public void warning( SAXParseException exception ) throws SAXException
{
throw exception;
}
...
之后,可以使用验证来验证类javax.xml.bind.util.JAXBSource
实例:
/**
* context is created and used to create sources for each country
*/
JAXBContext jaxbContext = JAXBContext.newInstance( Country.class );
JAXBSource sourceSpain = new JAXBSource( jaxbContext, spain );
JAXBSource sourceAustralia = new JAXBSource( jaxbContext, australia );
这是完整的程序:
/**
* error will be thrown because continent is mandatory
*/
Country spain = new Country();
spain.setName( "Spain" );
spain.setCapital( "Madrid" );
spain.setFoundation( LocalDate.of( 1469, 10, 19 ) );
spain.setImportance( 1 );
/**
* ok
*/
Country australia = new Country();
australia.setName( "Australia" );
australia.setCapital( "Camberra" );
australia.setFoundation( LocalDate.of( 1788, 01, 26 ) );
australia.setContinent( "Oceania" );
australia.setImportance( 1 );
/**
* schema is created
*/
SchemaFactory sf = SchemaFactory.newInstance( XMLConstants.W3C_XML_SCHEMA_NS_URI );
Schema schema = sf.newSchema( new File( "countries_validation.xsd" ) );
/**
* context is created and used to create sources for each country
*/
JAXBContext jaxbContext = JAXBContext.newInstance( Country.class );
JAXBSource sourceSpain = new JAXBSource( jaxbContext, spain );
JAXBSource sourceAustralia = new JAXBSource( jaxbContext, australia );
/**
* validator is initialized
*/
Validator validator = schema.newValidator();
validator.setErrorHandler( new MyErrorHandler() );
//validator is used
try
{
validator.validate( sourceSpain );
System.out.println( "spain has no problems" );
}
catch( SAXException ex )
{
ex.printStackTrace();
System.out.println( "spain has problems" );
}
try
{
validator.validate( sourceAustralia );
System.out.println( "australia has no problems" );
}
catch( SAXException ex )
{
ex.printStackTrace();
System.out.println( "australia has problems" );
}
及其输出:
org.xml.sax.SAXParseException
at javax.xml.bind.util.JAXBSource$1.parse(JAXBSource.java:248)
at javax.xml.bind.util.JAXBSource$1.parse(JAXBSource.java:232)
at com.sun.org.apache.xerces.internal.jaxp.validation.ValidatorHandlerImpl.validate(
...
spain has problems
australia has no problems
我们可以看到,澳大利亚没有问题,但是西班牙有……
使用XSD封送处理
XSD还用于从XML文件绑定和生成Java类,反之亦然。 我们将在这里看到如何通过编组示例使用它。
采用,我们将wriite是初始化程序前显示的相同的XML模式javax.xml.validation.Schema
使用给定的XSD和javax.xml.bind.JAXBContext
的类,我们要元帅( Country
)。 该程序将使用javax.xml.bind.Marshaller
来执行所需的操作:
/**
* validation will fail because continent is mandatory
*/
Country spain = new Country();
spain.setName( "Spain" );
spain.setCapital( "Madrid" );
spain.setFoundation( LocalDate.of( 1469, 10, 19 ) );
SchemaFactory sf = SchemaFactory.newInstance( XMLConstants.W3C_XML_SCHEMA_NS_URI );
Schema schema = sf.newSchema( new File( "countries_validation.xsd" ) );
JAXBContext jaxbContext = JAXBContext.newInstance( Country.class );
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty( Marshaller.JAXB_FORMATTED_OUTPUT, true );
marshaller.setSchema( schema );
//the schema uses a validation handler for validate the objects
marshaller.setEventHandler( new MyValidationEventHandler() );
try
{
marshaller.marshal( spain, System.out );
}
catch( JAXBException ex )
{
ex.printStackTrace();
}
/**
* continent is wrong and validation will fail
*/
Country australia = new Country();
australia.setName( "Australia" );
australia.setCapital( "Camberra" );
australia.setFoundation( LocalDate.of( 1788, 01, 26 ) );
australia.setContinent( "Australia" );
try
{
marshaller.marshal( australia, System.out );
}
catch( JAXBException ex )
{
ex.printStackTrace();
}
/**
* finally everything ok
*/
australia = new Country();
australia.setName( "Australia" );
australia.setCapital( "Camberra" );
australia.setFoundation( LocalDate.of( 1788, 01, 26 ) );
australia.setContinent( "Oceania" );
try
{
marshaller.marshal( australia, System.out );
}
catch( JAXBException ex )
{
ex.printStackTrace();
}
我们之前谈论的是与XSD相关的验证。 将对象编组为XML时也可以进行验证。 如果我们的对象不符合某些预期规则,尽管我们没有明确验证,但我们也会在这里遇到一些验证错误。 在这种情况下,我们没有使用实现org.xml.sax.ErrorHandler
的错误处理程序,而是javax.xml.bind.ValidationEventHandler
:
public class MyValidationEventHandler implements ValidationEventHandler
{
@Override
public boolean handleEvent( ValidationEvent event )
{
System.out.println( "Error catched!!" );
System.out.println( "event.getSeverity(): " + event.getSeverity() );
System.out.println( "event: " + event.getMessage() );
System.out.println( "event.getLinkedException(): " + event.getLinkedException() );
//the locator contains much more information like line, column, etc.
System.out.println( "event.getLocator().getObject(): " + event.getLocator().getObject() );
return false;
}
}
我们可以看到已经实现了javax.xml.bind.ValidationEventHandler.handleEvent(ValidationEvent)
方法。输出将是:
javax.xml.bind.MarshalException
- with linked exception:
[org.xml.sax.SAXParseException; lineNumber: 0; columnNumber: 0; cvc-pattern-valid: Value 'Australia' is not facet-valid with respect to pattern 'Asia|Europe|America|Africa|Oceania' for type 'continentType'.]
at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:311)
at ...
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Country>
<Country_Name>Australia</Country_Name>
<Country_Capital>Camberra</Country_Capital>
<Country_Foundation_Date>1788-01-26</Country_Foundation_Date>
<Country_Continent>Oceania</Country_Continent>
<Country_Population>0</Country_Population>
</Country>
显然,由于所有可能的规则星座及其应用非常庞大,因此关于XSD的解释还很多。 但是,这超出了本教程的范围。 如果您需要有关如何在JAXB中使用XML模式的更多信息,可以访问以下链接,我发现它们非常有趣:
- http://www.w3schools.com/schema/schema_example.asp 。
- http://blog.bdoughan.com/2010/12/jaxb-and-marshalunmarshal-schema.html 。
6.注释
在本教程中,我们一直在使用JAXB中用于XML封送和取消封送操作的几个批注。 我们将在这里列出最重要的一些:
-
XmlAccessorOrder
:此批注控制字段和属性在将以XML出现的类中的顺序。 有关更多信息:https ://docs.oracle.com/javase/7/docs/api/javax/xml/bind/annotation/XmlAccessorOrder.html -
XmlAccessorType
:指示元素是否应该序列化。 它与javax.xml.bind.annotation .XMLAccessType
结合使用。 有关更多信息: https : //docs.oracle.com/javase/7/docs/api/javax/xml/bind/annotation/XmlAccessorType.html -
XmlAnyAttribute
:将元素映射到通配符属性的映射。 有关更多信息,请参见http://docs.oracle.com/javase/7/docs/api/javax/xml/bind/annotation/XmlAnyAttribute.html 。 -
XmlAnyElement
:当未预定义映射时,用作取消编组操作的后备。 有关更多信息,请参见https://docs.oracle.com/javase/7/docs/api/javax/xml/bind/annotation/XmlAnyElement.html -
XmlAttribute
:此批注是最常用的批注之一。 它将Java元素(属性,属性,字段)映射到XML节点属性。 在本教程中已使用了几个示例。 有关更多信息,请参见https://docs.oracle.com/javase/7/docs/api/javax/xml/bind/annotation/XmlAttribute.html -
XmlElement
:使用名称将Java元素映射到XML节点。 有关更多信息,请参见https://docs.oracle.com/javase/7/docs/api/javax/xml/bind/annotation/XmlElement.html -
XmlElementRef
:使用其类型将Java元素映射到XML节点(不同于最后一个,该名称用于映射)。 有关此注释的更多信息,请参见https://docs.oracle.com/javase/7/docs/api/javax/xml/bind/annotation/XmlElementRef.html -
XmlElementRefs
:用XmlElement
或JAXBElement
标记引用类的属性。 有关更多信息, 请参见https://docs.oracle.com/javase/7/docs/api/javax/xml/bind/annotation/XmlElementRefs.html -
XmlElements
:这是多个XMLElement
批注的容器。 有关更多信息,请参见https://docs.oracle.com/javase/7/docs/api/javax/xml/bind/annotation/XmlElements.html -
XmlElementWrapper
:它围绕XML表示生成包装,该XML表示要与集合一起使用,在本教程中,我们看到了处理集合的不同方法。 有关更多信息, https://docs.oracle.com/javase/7/docs/api/javax/xml/bind/annotation/XmlElementWrapper.html -
XmlEnum
:提供枚举到XML表示形式的映射。 它与XmlEnumValue
结合使用。 有关更多信息,请访问https://docs.oracle.com/javase/7/docs/api/javax/xml/bind/annotation/XmlEnum.html -
XmlEnumValue
:将枚举常量映射到XML元素。 有关更多信息,请参见https://docs.oracle.com/javase/7/docs/api/javax/xml/bind/annotation/XmlEnumValue.html -
XmlID
:将属性映射到XML ID。 有关更多信息,请参见https://docs.oracle.com/javase/7/docs/api/javax/xml/bind/annotation/XmlID.html -
XmlList
:在JAXB中处理列表的另一种方法。 有关更多信息,请参见https://docs.oracle.com/javase/7/docs/api/javax/xml/bind/annotation/XmlList.html -
XmlMimeType
:控制带注释的属性的表示形式。 有关更多信息,请参见https://docs.oracle.com/javase/7/docs/api/javax/xml/bind/annotation/XmlMimeType.html -
XmlMixed
:带注释的元素可以包含混合内容。 内容可以是文本,子内容或未知内容。 有关更多信息,请参见https://docs.oracle.com/javase/7/docs/api/javax/xml/bind/annotation/XmlMixed.html -
XmlRootElement
:这可能是JAXB中最常用的注释。 它用于将类映射到XML元素。 它是每个JAXB表示形式的入口点。 有关更多信息, 请参见https://docs.oracle.com/javase/7/docs/api/javax/xml/bind/annotation/XmlRootElement.html -
XmlSchema
:将包映射到XML名称空间。 有关更多信息,请参见https://docs.oracle.com/javase/7/docs/api/javax/xml/bind/annotation/XmlSchema.html -
XmlSchemaType
:将Java类型映射为简单的模式内置类型。 有关更多信息,请参见https://docs.oracle.com/javase/7/docs/api/javax/xml/bind/annotation/XmlSchemaType.html -
XmlSeeAlso
:指示在绑定带注释的类时,JAXB绑定其他类。 之所以需要这样做,是因为Java很难列出给定类的所有子类,使用这种机制,您可以指示JAXB处理特定子类时应限制哪些子类(或其他类)。 有关更多信息, https://docs.oracle.com/javase/7/docs/api/javax/xml/bind/annotation/XmlSeeAlso.html -
XmlType
:用于将类或枚举映射到XML模式中的类型。 有关更多信息,请参见https://docs.oracle.com/javase/7/docs/api/javax/xml/bind/annotation/XmlType.html -
XmlValue
:允许将类映射到具有simpleContent或XML Schema简单类型的XML Schema复杂类型。 有关更多信息,请参见https://docs.oracle.com/javase/7/docs/api/javax/xml/bind/annotation/XmlValue.html
这是一个庞大的列表,但是这些并不是所有可用的JAXB相关注释。 有关带有所有JAXB可用注释的完整列表,请转到包摘要https://docs.oracle.com/javase/7/docs/api/javax/xml/bind/annotation/package-frame.html 。
7.工具
有许多工具可以帮助程序员在使用JAXB和XML Schema时使用。 我们将在本章中列出其中一些,并提供一些有用的资源:
-
schemagen
:代表模式生成器。 它用于从Java带注释的类或源生成JAXB Schema(它也适用于字节码)。 可以直接从命令行或使用Ant来使用。 有关更多信息,请访问Oracle页面https://docs.oracle.com/javase/7/docs/technotes/tools/share/schemagen.html或https://jaxb.java.net/2.2.4/docs/schemagen .html 。 它与JRE标准捆绑包一起提供,可以从bin目录中启动。 -
xjc
:这是JAXB绑定编译器。 它用于从XML模式(XSD)生成Java源(类)。 可以与Ant一起使用。 在执行XSD之前执行验证。 有关其用法和参数的更多信息,请访问https://jaxb.java.net/2.2.4/docs/xjc.html 。 -
Jsonix
:与JAXB无关,但是它是将XML转换为JSON的工具。 在使用JavaScript时,它非常有用。 这是官方链接http://confluence.highsource.org/display/JSNX/Jsonix 。 -
Hyperjaxb3
:它为JAXB对象提供关系持久性。 它使用JAXB批注将对象持久存储在关系数据库中。 它可以与Hibernate(可能是最常用的Java持久性框架)一起使用。 您可以在链接http://confluence.highsource.org/display/HJ3/Home中找到更多文档和资源。 - Maven JAXB2插件:Maven插件,提供了xjc工具的所有功能以及将XML Schema转换为Java类时的更多功能。 在以下链接中,您可以下载资源并查阅文档https://github.com/highsource/maven-jaxb2-plugin 。
- JAXB Eclipse插件:有几个可用的Eclipse插件(也适用于其他IDE,例如NetBeans或IntelliJ),可以将XML Schema编译为Java类,验证XML模式或生成模式。 它们全部包装并使用上述工具之一。 由于没有可被描述为标准插件的插件,我让您在网络上搜索并选择一个插件。
这些并不是与JAXB和XSD一起使用的用于将XML结构转换为Java类的所有工具。 还有更多。 我只是在这里列出了每个开发人员在其应用程序中使用JAXB时应考虑的最重要和最基本的内容。
8.最佳做法
尽管这不是最佳实践的完整列表,并且它是一个主观主题,但我想给出一些与JAXB相关的首选用法。
- 尽量避免出现有问题的原始类型,例如
float
,decimal
或negativeInteger
; 这些在JAXB中没有相关类型。 在这些情况下,您可能可以使用其他“无问题”原始类型。 - 使用注释
@XMLSchemaType
可以更明确地说明必须使用的类型,并且不要让JAXB来决定这一点。 - 避免匿名类型和混合内容。
- JAXB使用系统默认的语言环境和国家/地区来生成信息和错误消息。为了进行更改,您可以将以下JVM参数传递给应用程序:
-Duser.country=US -Duser.language=en -Duser.variant=Traditional_WIN
9.总结
这就是全部。 在本教程中,我们解释了什么是JAXB以及它可以用于什么。 JAXB代表用于XML绑定的Java体系结构,它基本上是用于以下目的的框架:
- 将Java对象编组为XML结构。
- 将XML文件取消编组为Java类。
- 这些操作可以使用XSD(XML模式)来完成。
- XSD对于验证目的也非常有用。
简而言之,JAXB可用于将XML转换为Java类,反之亦然。 我们解释了与所有这些相关的主要概念,并列出了JAXB使用中涉及的主要注释和类。
有几种工具可以与JAXB结合使用,以用于不同的目的,我们解释了如何使用它们以及可以对其中的某些工具进行处理。
10.资源
本教程包含有关JAXB及其将XML编组和解编为Java对象的用法的深入信息。 它还说明了在使用JAXB时如何使用XSD,以及一些最佳实践和技巧。 但是,如果您需要在使用JAXB进行应用程序编程方面迈出一步,那么访问以下资源可能会很有用:
- https://examples.javacodegeeks.com/core-java/xml/bind/jaxb-unmarshal-example/
- https://examples.javacodegeeks.com/core-java/xml/bind/jaxb-unmarshal-example/
- http://www.oracle.com/technetwork/articles/javase/index-140168.html
- http://en.wikipedia.org/wiki/Java_Architecture_for_XML_Binding
- https://jaxb.java.net/
- http://en.wikipedia.org/wiki/XML_schema
11.下载Java XML绑定的JAXB教程源代码
这是Java XML绑定的JAXB教程。
翻译自: https://www.javacodegeeks.com/2014/12/jaxb-tutorial-xml-binding.html
jaxb