JAXB简介与简单入门

JAXB简介与简单入门

  • 作者:Geticsen
  • 时间:2020-11-30
  • 259人已阅读
简介 JAXB(Java Architecture for XML Binding) 是一个业界的标准,是一项可以根据XML Schema产生Java类的技术,本文将带大家简单学习

JAXB是什么

JAXB(Java Architecture for XML Binding) 是一个业界的标准,是一项可以根据XML   Schema产生Java类的技术。该过程中,JAXB也提供了将XML实例文档反向生成Java对象树的方法,并能将Java对象树的内容重新写到XML实例文档。从另一方面来讲,JAXB提供了快速而简便的方法将XML模式绑定到Java表示,从而使得Java开发者在Java应用程序中能方便地结合XML数据和处理函数。

简单上手

既然是java类生成xml和xml生成java类的处理方法,简单的案例也从这里开始,需要声明一下JAXB已经被jdk8封装不需要额外的包,当然如果你需要自己定制可以导入外部包然后重写一些方法。

JAXB的包在 javax.xml.bind.annotation

image.png

案例一

package auto.sort.email;

import javax.xml.bind.JAXB;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.io.File;

@XmlRootElement
class Person{
    private Integer age;
    private String sex;
    private String name;

    public Integer getAge() {
        return age;
    }
    @XmlElement
    public void setAge(Integer age) {
        this.age = age;
    }

    public String getSex() {
        return sex;
    }
    @XmlElement
    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getName() {
        return name;
    }
    @XmlElement
    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "{age:"+age+ ",sex:"+sex+ ",name:"+name+"}";
    }

    public Person(Integer age, String sex, String name) {
        this.age = age;
        this.sex = sex;
        this.name = name;
    }

    public Person() {
    }
}
public class JaxbDemo {
    public static void main(String[] args) {
        generateXML();
        generateBean();
    }

    public static void generateXML() {
        Person person = new Person(12, "女", "jack");
        File file = new File("E:\\JavaFile\\person.xml");
        JAXB.marshal(person, file);
    }
    public static void generateBean() {
        File file = new File("E:\\JavaFile\\person.xml");
        Person person = JAXB.unmarshal(file, Person.class);
        System.out.println(person);
    }
}

如上代码generateXML方法会生成person对象所对应的Xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<person>
    <age>12</age>
    <name>jack</name>
    <sex>女</sex>
</person>

generateBean会将generateXML生成的XML转化为Java对象

输出结果如下:

{age:12,sex:女,name:jack}

我们可以看到在javax.xml.bind.annotation下有非常多的注解下面我们开始简单了解一下

image.png

@XmlRootElement:

作用和用法:

类级别的注解,将类映射为xml全局元素,也就是根元素。就像spring配置文件中的beans。上面的例子中我将该注解用在了person类上,生成了<person>根元素。常与@XmlType,@XmlAccessorType,@XmlAccessorOrder连用。

属性:

该注解含有name和namespace两个属性。namespace属性用于指定生成的元素所属的命名空间。name属性用于指定生成元素的名字,若不指定则默认使用类名小写作为元素名。修改上面的例子,在该注解上使用name属性

案例二

我们将如上@XmlRootElement的属性添加上

@XmlRootElement(namespace = "com.jaxb.demo",name = "mankind")
class Person{
 //内部不变,这里省略
}

我们运行后得到

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:mankind xmlns:ns2="com.jaxb.demo">
    <age>12</age>
    <name>jack</name>
    <sex>女</sex>
</ns2:mankind>

这里可以简单的理解如上的属性添加上以后会对生成的xml做出规范添加命名空间以及重新命名。

案例三

我相信通过以上的案例你已经基本了解了JAXB的基本使用以及XML和JavaBean之间的转化了

现在开始我们来看点有难度的,如上我们已经知道了JAXB的实现中用到了很多注解这么多注解我们怎么学习呢,你可以一个一个百度但是我建议你可以看看源码。

我们以@XmlElement为例(我是用的IDEA编写代码,eclipse会有所不同)

在代码中随意找一个有@XMLElement的注解先将@XmlElement后面加上括号,然后按住Ctrl +p 会出现参数列表(Tips:Ctrl +p也可以查看任意的java方法的参数列表,如果这个函数有重载则会显示多个参数列表)

image.png

这个时候我们虽然知道这里面可以填什么但是不知道是什么意思,这时候我们先将鼠标置于XmlElement注解上  按住Ctrl 待其变蓝色 点击即可进入查看源码说明。

/*
 * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */

package javax.xml.bind.annotation;

import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.RetentionPolicy.*;

@Retention(RUNTIME) @Target({FIELD, METHOD, PARAMETER})
public @interface XmlElement {
    /**
     * Name of the XML Schema element.
     * <p> If the value is "##default", then element name is derived from the
     * JavaBean property name.
     */
    String name() default "##default";

    /**
     * Customize the element declaration to be nillable.
     * <p>If nillable() is true, then the JavaBean property is
     * mapped to a XML Schema nillable element declaration.
     */
    boolean nillable() default false;

    /**
     * Customize the element declaration to be required.
     * <p>If required() is true, then Javabean property is mapped to
     * an XML schema element declaration with minOccurs="1".
     * maxOccurs is "1" for a single valued property and "unbounded"
     * for a multivalued property.
     * <p>If required() is false, then the Javabean property is mapped
     * to XML Schema element declaration with minOccurs="0".
     * maxOccurs is "1" for a single valued property and "unbounded"
     * for a multivalued property.
     */

    boolean required() default false;

    /**
     * XML target namespace of the XML Schema element.
     * <p>
     * If the value is "##default", then the namespace is determined
     * as follows:
     * <ol>
     *  <li>
     *  If the enclosing package has {@link XmlSchema} annotation,
     *  and its {@link XmlSchema#elementFormDefault() elementFormDefault}
     *  is {@link XmlNsForm#QUALIFIED QUALIFIED}, then the namespace of
     *  the enclosing class.
     *
     *  <li>
     *  Otherwise &#39;&#39; (which produces unqualified element in the default
     *  namespace.
     * </ol>
     */
    String namespace() default "##default";

    /**
     * Default value of this element.
     *
     * <p>
     * The <pre>'\u0000'</pre> value specified as a default of this annotation element
     * is used as a poor-man's substitute for null to allow implementations
     * to recognize the 'no default value' state.
     */
    String defaultValue() default "\u0000";

    /**
     * The Java class being referenced.
     */
    Class type() default DEFAULT.class;

    /**
     * Used in {@link XmlElement#type()} to
     * signal that the type be inferred from the signature
     * of the property.
     */
    static final class DEFAULT {}
}

这时候很多人就会放弃了因为全部都是英文,但其实呢也很简单你可以用百度翻译,或者谷歌翻译来帮助你理解。

@Retention(RUNTIME) @Target({FIELD, METHOD, PARAMETER})
public @interface XmlElement {
    /**
     *  XML 中元素的名称.如果其值是 默认值(也就是没有指定)则其名字就是JavaBean的属性名 
     */
    String name() default "##default";

    /**
     * 自定义元素是否可以为null,如果为true然后JavaBean属性被映射到XML模式的nillable元素声明。
     */
    boolean nillable() default false;

    /**
    *自定义所需的元素声明。如果required()为true,则Javabean属性映射到minOccurs=“1”的XML模式元素声明。
    *对于单值属性,maxOccurs为“1”,而“unbounded”对于多值属性。如果required()为false,则映射Javabean属性minOccurs=“0”的XML架构元素声明。
    *对于单值属性,maxOccurs为“1”,而“unbounded”对于多值属性。
    */

    boolean required() default false;

    /**
    * XML架构元素的XML目标命名空间。
    *如果值是“###default”,则确定名称空间
    *具体如下:
    *如果封闭包有{@link XmlSchema}批注,
    *及其{@link XmlSchema#elementFormDefault()elementFormDefault}
    *{@link XmlNsForm}是限定的,则
    *封闭类。
    *否则(在默认命名空间中生成非限定元素)。
    */
    String namespace() default "##default";

    /**
     * 元素的默认值.指定为此批注元素的默认值
     *被用作空值的穷人替代品,以允许实现
     *识别“无默认值”状态。
     */
    String defaultValue() default "\u0000";

    /**
     * java被引用的类.
     */
    Class type() default DEFAULT.class;

    /**
     * 使用{@link XmlElement#type()} 去
     * 指示从属性的签名推断类型。
     */
    static final class DEFAULT {}
}

那我们以name 属性为例

在Person类中指定name字段@XmlElement注解中name属性的值为 firstName

@XmlElement(name = "firstName")
public void setName(String name) {
    this.name = name;
}

运行代码得到Xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:mankind xmlns:ns2="com.jaxb.demo">
    <age>12</age>
    <firstName>jack</firstName>
    <sex>女</sex>
</ns2:mankind>

name这个属性如注释所说

 XML 中元素的名称.如果其值是 默认值(也就是没有指定)则其名字就是JavaBean的属性名

指定之后就是指定的值。

总结

JAXB技术是一种XML和javaBean相互转换的技术,其可以极大的便利我们在解析xml的工作,xml作为web技术的基础其有高扩展性与强规范的特点广泛用于数据交互,JAXB的使用也是比较广泛的,但就技术上来说是不太难的,但是要将其灵活的用起来还是要很多时间的。

文章评论

Top