Статьи

Учебное пособие по JAXB для Java XML Binding — ULTIMATE Guide (PDF Download)

В этой статье мы расскажем о всеобъемлющем руководстве по JAXB для связывания Java XML. Java предлагает несколько вариантов обработки XML-структур и файлов. Одним из наиболее распространенных и используемых является JAXB. JAXB означает Java Architecture для привязки XML. Он предлагает возможность конвертировать объекты Java в структуры XML и наоборот. JAXB поставляется со стандартным пакетом JRE начиная с первых версий JRE 1.6.

Первая спецификация JAXB была сделана в марте 2003 года, и рабочий процесс отслеживается в Запросе спецификации Java 31: https://jcp.org/en/jsr/detail?id=31 . В этом запросе спецификации вы можете найти много информации о долгом сроке службы JAXB и обо всех сделанных улучшениях.

Как уже упоминалось, JAXB включен в комплект JRE с момента обновления 1.6. До этого необходимо было включать их библиотеки в конкретный проект Java, чтобы иметь возможность использовать его.

До того, как JAXB был доступен (давным-давно), Java должен был обрабатывать XML-документы как DOM: http://www.w3.org/DOM/ . Это был не очень хороший подход, потому что почти не было абстракции от узлов XML в объекты Java, и все типы значений были выведены в виде строк. JAXB предоставляет несколько преимуществ, таких как объектно-ориентированный подход, связанный с узлами и атрибутами XML, типизированными значениями, аннотациями и другими, которые мы собираемся объяснить в этой статье.

Все примеры в этом руководстве были реализованы с использованием следующих версий программного обеспечения: JRE 1.8.0 для 32b. В качестве IDE используется Eclipse SDK Version: Luna (4.4). Однако любые другие версии Java, содержащие JAXB API и IDE, должны прекрасно работать, поскольку весь код является стандартным Java 8.

1. Картирование

Java-объекты могут быть связаны со структурами XML, используя определенные аннотации и следуя определенным правилам. Это то, что мы называем картированием. В этом уроке мы собираемся объяснить следующие моменты, предоставив примеры, ресурсы и дополнительную информацию:

  • Мы собираемся показать несколько примеров того, как преобразовать объекты Java в структуры XML, это называется маршалингом. Мы покажем, как обрабатывать примитивные типы, коллекции и более сложные типы с помощью адаптеров.
  • Мы также объясним, как выполнить дополнительную операцию, называемую немаршалингом, то есть преобразование файлов XML в объекты Java.
  • Все это делается с помощью аннотаций Java, мы перечислим и объясним наиболее важные аннотации, используемые в JAXB.
  • Мы также предоставим введение в XSD (XML-схемы), которые используются для проверки и являются мощным инструментом, поддерживаемым JAXB. Мы увидим, как XSD можно использовать и для сортировки.
  • Наконец, мы перечислим несколько инструментов, которые можно использовать в сочетании с JAXB, которые по-разному помогают программистам.

2. Маршал

В этой главе мы рассмотрим, как преобразовать объекты Java в файлы XML и что следует учитывать при выполнении этой операции. Это обычно называется маршалингом.

Прежде всего, мы указываем JAXB, какие элементы java из нашей бизнес-модели соответствуют каким узлам XML.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
@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 в сочетании с методами установки.
  • @XmlAttribute для передачи атрибутов узлам XML. Эти атрибуты могут иметь свойства, такие как обязательные или нет.
  • @XmlType для указания специальных параметров, таких как порядок появления в XML.

Мы объясним эти и другие аннотации более подробно в следующих главах. На данный момент я просто хочу упомянуть их здесь.

Следующим шагом является создание файлов XML из объектов Java. Для этого мы создаем простую тестовую программу, использующую JAXBContext и его функции маршалинга:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
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-объектах и ​​является точкой входа в API JAXB. Дополнительную информацию об этом классе можно найти здесь: https://docs.oracle.com/javase/7/docs/api/javax/xml/bind/JAXBContext.html .

В нашем небольшом примере мы просто используем этот класс для создания контекста JAXB, который позволяет нам маршалировать объекты типа, переданного в качестве параметра. Это сделано именно здесь:

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

Результатом основной программы будет:

1
2
3
4
5
6
7
8
<?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, мы можем написать:

01
02
03
04
05
06
07
08
09
10
11
12
13
@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, что класс, содержащий список, присутствует. В результате программа, подобная показанной выше, будет выглядеть так:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
<?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, которую мы хотим разархивировать:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
<?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:

1
2
3
4
5
6
7
8
9
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 . Это выглядит как:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
@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;
    }
...

Мы не можем оценить слишком много различий с классами, использованными в предыдущей главе, используются те же аннотации.

Это вывод, произведенный программой в стандартной консоли:

1
2
3
4
5
6
7
8
9
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 .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
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 интерфейса javax.xml.bind.annotation.adapters.XmlAdapter с надлежащими типами и результатами, а затем мы указываем JAXB, где его использовать, используя аннотацию @XmlJavaTypeAdapter :

1
2
3
4
5
6
7
8
...
@XmlElement( name = "Country_Foundation_Date" )
@XmlJavaTypeAdapter( DateAdapter.class )
public void setFoundation( LocalDate foundation )
{
    this.foundation = foundation;
}
...

Результирующий XML для первой программы, показанной в этом руководстве, будет выглядеть примерно так:

1
2
3
4
5
6
7
8
<?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>

Это может быть применено к любому другому сложному типу, не поддерживаемому JAXB напрямую, который мы хотели бы иметь в наших структурах XML. Нам просто нужно реализовать интерфейс 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 для проверки и маршалинга.

Вот пример XML-схемы, которую можно использовать для класса Country используемого в этом руководстве:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
<?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>

5.1. Проверка с использованием XSD

XSD могут быть использованы для проверки XML. JAXB использует XSD для проверки XML и обеспечения того, чтобы объекты и структуры XML следовали набору ожидаемых правил. Чтобы проверить объект по XSD, нам нужно сначала создать XSD, например:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
<?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 и инициализировав его проверку следующим образом:

1
2
3
4
5
/**
* 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 и его методов ошибок:

01
02
03
04
05
06
07
08
09
10
public class MyErrorHandler implements ErrorHandler
{
 
    @Override
    public void warning( SAXParseException exception ) throws SAXException
    {
        throw exception;
 
    }
   ...

После этого проверка может использоваться для проверки экземпляров класса javax.xml.bind.util.JAXBSource :

1
2
3
4
5
6
/**
 * 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 );

Вот полная программа:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/**
   * 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" );
  }

и его вывод:

1
2
3
4
5
6
7
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

Мы видим, что у Австралии нет проблем, а у Испании…

5.2. Маршалинг с использованием XSD

XSD используются также для связывания и генерации Java-классов из XML-файлов и наоборот. Здесь мы увидим, как использовать его с примером маршалинга.

Используя ту же XML-схему, показанную ранее, мы собираемся написать программу, которая инициализирует javax.xml.validation.Schema используя заданный XSD и javax.xml.bind.JAXBContext для классов, которые мы хотим маршалировать ( Country ). Эта программа будет использовать javax.xml.bind.Marshaller для выполнения необходимых операций:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
/**
 * 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 :

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
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) был реализован.
И вывод будет:

01
02
03
04
05
06
07
08
09
10
11
12
13
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 можно рассказать гораздо больше из-за возможных комбинаций правил и их приложений. Но это выходит за рамки этого урока. Если вам нужна дополнительная информация о том, как использовать XML-схемы в JAXB, вы можете посетить следующие ссылки, я нашел их действительно интересными:

6. Аннотации

В этом уроке мы использовали несколько аннотаций, используемых в JAXB для операций маршалинга и демаршалинга в XML. Мы собираемся перечислить здесь самые важные из них:

Это огромный список, но это не все доступные аннотации, связанные с JAXB. Для получения полного списка со всеми доступными аннотациями JAXB перейдите к сводной информации о пакете https://docs.oracle.com/javase/7/docs/api/javax/xml/bind/annotation/package-frame.html .

7. Инструменты

Есть много инструментов, которые могут помочь программистам при работе с JAXB и XML-схемами. Мы собираемся перечислить в этой главе некоторые из них и предоставить некоторые полезные ресурсы:

Это не все инструменты, которые работают с JAXB и XSD для преобразования структур XML в классы Java. Есть много других. Я просто перечислил здесь самые важные и основные из них, которые каждый разработчик должен учитывать при использовании JAXB в своих приложениях.

8. Лучшие практики

Хотя это не полный список лучших практик и это субъективная тема, я хотел бы привести пару предпочтений, связанных с JAXB.

  • Старайтесь избегать проблемных примитивных типов, таких как float , decimal или negativeInteger ; у них нет связанного типа в JAXB. В этих случаях вы, вероятно, можете использовать другие «не проблемные» примитивные типы.
  • Используйте аннотацию @XMLSchemaType чтобы быть более явным в отношении типа, который должен использоваться, и не оставляйте JAXB, чтобы решить этот вопрос.
  • Избегайте анонимных типов и смешанного контента.
  • JAXB использует системный язык и страну по умолчанию для генерации информации и сообщений об ошибках. Чтобы изменить это, вы можете передать в приложение следующие параметры JVM:
    1
    -Duser.country=US -Duser.language=en -Duser.variant=Traditional_WIN

9. Резюме

Ну вот и все. В этом уроке мы объяснили, что такое JAXB и для чего его можно использовать. JAXB расшифровывается как Java Architecture для привязки XML, и это платформа, используемая в основном для:

  • Маршалинг Java-объектов в XML-структуры.
  • Немаршалинг XML-файлов в классы Java.
  • Эти операции могут быть выполнены с использованием XSD (схемы XML).
  • XSD очень полезны и для проверки.

Проще говоря, JAXB можно использовать для преобразования XML в классы Java и наоборот. Мы объяснили основные понятия, связанные со всем этим, и перечислили основные аннотации и классы, связанные с использованием JAXB.

Существует несколько инструментов, которые можно использовать в сочетании с JAXB для различных целей, мы объяснили, как их использовать и что можно сделать с некоторыми из них.

10. Ресурсы

Это руководство содержит подробную информацию о JAXB и его использовании для маршалинга и демаршалирования XML в объекты Java. Также объясняется, как использовать XSD при работе с JAXB, а также некоторые рекомендации и приемы. Но если вам нужно сделать шаг вперед в разработке приложений с помощью JAXB, может быть полезно посетить следующие ресурсы:

11. Загрузите Учебное пособие по JAXB для Java XML Binding Source.

Это было учебное пособие по JAXB по связыванию Java XML.