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

一、先看个简单的例子

实体类:UserInfo.java 

package com.demo.bean;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.Arrays;

@XmlRootElement
public class UserInfo {
    private int id;
    private String name;
    private String gender;
    private String addr;
    private String[] hobbys;

    public UserInfo() {
    }

    public UserInfo(int id, String name, String gender, String addr, String[] hobbys) {
        this.id = id;
        this.name = name;
        this.gender = gender;
        this.addr = addr;
        this.hobbys = hobbys;
    }
    @XmlElement
    public int getId() {
        return id;
    }

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

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

    public void setGender(String gender) {
        this.gender = gender;
    }
    @XmlElement
    public String getAddr() {
        return addr;
    }

    public void setAddr(String addr) {
        this.addr = addr;
    }
    //使用@XmlElementWrapper注解后,将会在原xml结点上再包装一层xml
    //@XmlElementWrapper仅允许出现在集合属性上
    @XmlElementWrapper(name="allhobbys")
    @XmlElement(name="hobby")
    public String[] getHobbys() {
        return hobbys;
    }

    public void setHobbys(String[] hobbys) {
        this.hobbys = hobbys;
    }

    @Override
    public String toString() {
        return "UserInfo{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", gender='" + gender + '\'' +
                ", addr='" + addr + '\'' +
                ", hobbys=" + Arrays.toString(hobbys) +
                '}';
    }
}

实战互转方法

import com.demo.bean.UserInfo;
import org.junit.Test;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.File;
import java.io.StringReader;
import java.io.StringWriter;

public class Test01 {
    @Test
    public void test(){
        UserInfo user = new UserInfo(1,"张三","男","杭州",new String[]{"篮球","音乐"});
        String xmlStr = objToXML(user);
        System.out.println(xmlStr);
        System.out.println("---------------------------------------------------------------");
        UserInfo getUser = (UserInfo)xmlStrToObj(xmlStr,UserInfo.class);
        System.out.println(getUser);
        System.out.println("---------------------------------------------------------------");
        //编组输出到文件中
        objToXmlFile(user,"E:\\user.xml");
        UserInfo getUser1 = (UserInfo)xmlFileToObj("E:\\user.xml",UserInfo.class);
        System.out.println(getUser1);
    }

    public String objToXML(Object obj){
        try {
            //根据obj类生成上下文对象
            JAXBContext context = JAXBContext.newInstance(obj.getClass());
            //从上下文中获取Marshaller对象,用作将bean编组(转换)为xml
            Marshaller marshaller = context.createMarshaller();
            //设置编码格式(默认编码就是utf-8)
            marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");//GB2312
            //以下是为生成xml做的一些配置
            //是否格式化生成的xml,即按标签自动换行,否则就是一行输出
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.FALSE);
            // 是否省略xml头部信息,默认不省略(false)
            marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
            StringWriter stringWriter = new StringWriter();
            marshaller.marshal(obj, stringWriter);
            StringBuilder stringBuilders = new StringBuilder();
            return stringBuilders.append(stringWriter).toString();
        } catch (JAXBException e) {
            e.printStackTrace();
        }
        return null;
    }

    public void objToXmlFile(Object obj,String fileUrl){
        try {
            File file = new File(fileUrl);
            //根据obj类生成上下文对象
            JAXBContext context = JAXBContext.newInstance(obj.getClass());
            //从上下文中获取Marshaller对象,用作将bean编组(转换)为xml
            Marshaller marshaller = context.createMarshaller();
            //设置编码格式(默认编码就是utf-8)
            marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");//GB2312
            //以下是为生成xml做的一些配置
            //是否格式化生成的xml,即按标签自动换行,否则就是一行输出
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
            // 是否省略xml头部信息,默认不省略(false)
            marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
            marshaller.marshal(obj,file);
        } catch (JAXBException e) {
            e.printStackTrace();
        }
    }

    public Object xmlStrToObj(String xmlStr,Class objClass){
        try {
            JAXBContext jc = JAXBContext.newInstance(objClass);
            Unmarshaller unmar = jc.createUnmarshaller();
            Object obj = unmar.unmarshal(new StringReader(xmlStr));
            return obj;
        } catch (JAXBException e) {
            e.printStackTrace();
        }
        return null;
    }

    public Object xmlFileToObj(String xmlFileUrl,Class objClass){
        try {
            File file = new File(xmlFileUrl);
            JAXBContext jc = JAXBContext.newInstance(objClass);
            Unmarshaller unmar = jc.createUnmarshaller();
            Object obj = unmar.unmarshal(file);
            return obj;
        } catch (JAXBException e) {
            e.printStackTrace();
        }
        return null;
    }
}

输出结果:

生成的user.xml文件

二、常用注解解析

1、@XmlRootElement

作用和用法:

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

属性:

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

2、@XmlElement

作用和用法:

  字段,方法,参数级别的注解。该注解可以将被注解的字段(非静态),或者被注解的get/set方法对应的字段映射为本地元素,也就是子元素。默认使用字段名或get/set方法去掉前缀剩下部分小写作为元素名(在字段名和get/set方法符合命名规范的情况下)。上面例子中,id、addr、name、gender、hobby 都被映射成了<person>元素的子元素。下文会配合@XmlAccessorType注解详细讲解该注解的用法。常与@XmlValue,@XmlJavaTypeAdapter,@XmlElementWrapper连用。

属性:

  该注解的属性常用的属性有有:name、nillable、required、namespace、defaultValue

  • name属性可以指定生成元素的名字,同@XmlRootElement注解的name属性一样,不再举例。
  • nillable属性可以指定元素的文本值是否可以为空,默认为false。
  • required属性可以指定该元素是否必须出现,默认为false。
  • namespace属性可以指定该元素所属的命名空间。
  • defaultValue属性可以指定该元素默认的文本值。

3、@XmlAttribute

作用和用法:

字段和方法级别的注解。该注解会将字段或get/set方法对应的字段映射成本类对应元素的属性,属性名默认使用字段名或get/set方法去掉前缀剩下部分首字母小写(在字段名和get/set方法符合命名规范的情况下)。修改上面例子:

属性:

  该注解有name,required,namespace三个属性。用法和@XmlElement注解相同。

4、@XmlTransient

作用和用法:

  类,字段,方法级别的注解。可使JAXB在映射xml元素时忽略被注解的类,字段,get/set对应字段。需要注意的是该注解与所有其他JAXB注释相互排斥,也就是说与其他注释连用就会报错。修改上面例子:

属性:

  该注解没有属性。

5、@XmlJavaTypeAdapter

作用和用法:

  包、类、字段,方法、参数级别的注解。解决java日期(Date),数字(Number)格式化问题。直接看例子,修改UserInfo类,添加一个Date类型字段:

自定义一个适配器来解决这个问题。该注解的用法就是自定义适配器并继承XmlAdapter类,实现里面的marshal和unmarshal方法,并在该注解上引用。修改例子:

自定义的DateAdapter:

public class DateAdapter extends XmlAdapter<String, Date> {
    private static final SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd");

    @Override
    public Date unmarshal(String date) throws Exception {
        return SDF.parse(date);
    }

    @Override
    public String marshal(Date date) throws Exception {
        return SDF.format(date);
    }
}

6、@XmlAccessorOrder

作用和用法:

  包和类级别的注解。控制生成元素的顺序。

属性:

  只有一个value属性,可取的值是一个名为XmlAccessOrder的枚举类型的两个值,XmlAccessOrder.ALPHABETICAL 和 XmlAccessOrder.UNDEFINED。默认为XmlAccessOrder.UNDEFINED,代表按照类中字段的顺序生成元素的顺序。

另一个值则代表按照字母表的顺序对生成的元素排序。但奇怪的是,只有jaxb按照field生成元素时,默认值才会生效,否则总是按照字母表的顺序排序。

7、@XmlAccessorType

作用和用法:

  包和类级别的注解。javaEE的API对该注解的解释是:控制字段是否被默认序列化。通俗来讲,就是决定哪些字段或哪些get/set方法对应的字段会被映射为xml元素,需要注意的是字段或get/set方法的访问权限(public/private)会影响字段是否被映射为xml元素,下面会详细讲解。

属性:

  该注解只有一个value属性,可取的值是一个名为XmlAccessType的枚举类型里的值,下面详细看一下这几个值分别有什么用:

XmlAccessType.PROPERTY:

1.当使用了该值,只要字段有对应的get/set方法对(注意是成对出现,只有其中一个不会发生映射),不需要使用@XmlElement注解,不论该方法的访问权限是什么(即使是private),jaxb就会将该字段映射成xml元素。不过最好加上@XmlElement注解,get/set方法任选一个即可,都加上会报错。

2.若在一个字段有set/get方法对但又在字段上添加@XmlElement注解会报属性重复的错误。

3.若没有set/get方法对,则需要在字段上使用@XmlElement注解才可以映射为xml元素,否则不会发生映射。

4.若get/set方法上使用了@XmlTransient注解,但想要对应字段发生映射,需要在对应字段上添加@XmlElement注解,此时不会报错,并将该字段映射为xml元素。

XmlAccessType.FIELD:

1.每个非静态的字段(无论访问权限如何)都会被jaxb映射为xml元素,即使没有get/set方法对,即使没有使用@XmlElement元素,但最好加上该注解以表明该字段要被映射为xml元素。

2.虽然没有get/set方法对,也会发生映射,但加上get/set方法对也不会报错,因为我们经常会使用这两个方法。但注意,不能再在这两个方法上使用@XmlElement方法,否则会报属性重复的错误。

3.若在字段上使用了@XmlTransient注解,但还想让该字段发生映射,需要在该字段对应的get/set方法上添加@XmlElement

XmlAccessType.PUBLIC_MEMBER: (该值为默认值):

1.每个访问权限为public的字段,或者每个访问权限为public的get/set方法对,都会将字段映射为xml元素,即使不使用@XmlElement,但最好加上。不可同时存在public字段和对应的get/set方法对,不然会报属性重复的错误。

2.若使用@XmlElement注解,需要注意只能在字段或get/set方法添加,两者任选其一,否则会报属性重复的错误。

3.若字段不为public,get/set方法为public并使用了@XmlTransient,需要在字段上添加@XmlElement才会发生映射。

若字段为public并使用了@XmlTransient,get/set方法对不为public,需要在get/set方法上使用@XmlElement才会映射。

XmlAccessType.NONE:

任何字段,get/set方法对都不会发生映射,除非使用某些注解,如@XmlElement,@XmlElementWrapper等。

JAXB java类与xml互转的更多相关文章

  1. JAXB—Java类与XML文件之间转换

    JAXB-Java类与XML文件之间转换 简介         JAXB(Java Architecture for XML Binding) 是一个业界的标准,是一项可以根据XML Schema产生 ...

  2. JAVA bean与XML互转的利器---XStream

    最近在项目中遇到了JAVA bean 和XML互转的需求, 本来准备循规蹈矩使用dom4j忽然想起来之前曾接触过的XStream, 一番研究豁然开朗,利器啊利器, 下来就XStream的一些用法与大家 ...

  3. 使用JDK自带的JAXB进行类和xml的互转

    Classroom.java public class Classroom { private int id; private String name; private int grade; publ ...

  4. 简单Java类与XML之间的转换

    需要的jar包:xmlpull_1_0_5.jar,xstream-1.4.1.jar) 1.工具类XstreamUtil package com.learn.util; import com.tho ...

  5. JAXB(Java Architecture for XML Binding)

    marshal(Java对象转化成XML) import javax.xml.bind.annotation.XmlRootElement; //指定根元素,其他属性默认为根元素的子元素 @XmlRo ...

  6. Java Jaxb JavaBean与XML互转

    1.Jaxb - Java Arcitecture for XML Binding 是业界的一个标准,是一项能够依据XML Schema产生Java类的技术. Jaxb2.0是Jdk1.6的组成部分. ...

  7. JAXB 实现java对象与xml之间互相转换

    首先熟悉一下JAXB实现对象与xml互转时常用的一些注解使用: 1.@XmlRootElement,用于类级别的注解,对应xml的跟元素.通过name属性定义这个根节点的名称. 2.@XmlAcces ...

  8. jaxb 专题一(JAXB 实现java对象与xml之间互相转换)

    首先熟悉一下JAXB实现对象与xml互转时常用的一些注解使用: 1.@XmlRootElement,用于类级别的注解,对应xml的跟元素.通过name属性定义这个根节点的名称. 2.@XmlAcces ...

  9. java生成解析xml的另外两种方法JAXB

     JAXB(Java Architecture for XML Binding) 是一个业界的标准,是一项可以根据XML Schema产生Java类的技术.该过程中,JAXB也提供了将XML实例文档反 ...

随机推荐

  1. How to use the windows active directory to authenticate user via logon form 如何自定义权限系统,使用 active directory验证用户登录

    https://www.devexpress.com/Support/Center/Question/Details/Q345615/how-to-use-the-windows-active-dir ...

  2. WinForm 捕获系统关机、重启、注销事件

    Public Class App Public Shared Sub Main() ' 关联事件 AddHandler Microsoft.Win32.SystemEvents.SessionEndi ...

  3. 【转载】钉钉开发c#帮助类 获取用户信息 DingHelper.cs

    using System;using System.Collections.Generic;using System.Configuration;using System.Linq;using Sys ...

  4. TensorFlow Python2.7环境下的源码编译(一)环境准备

    参考: https://blog.csdn.net/yhily2008/article/details/79967118 https://tensorflow.google.cn/install/in ...

  5. lua字符串类型

    Lua中字符串结构体的定义是: typedef union TString { L_Umaxalign dummy; /* ensures maximum alignment for strings ...

  6. mysql读写分离配置(整理)

    mysql读写分离配置 环境:centos7.2 mysql5.7 场景描述: 数据库Master主服务器:192.168.206.100 数据库Slave从服务器:192.168.206.200 M ...

  7. shell解析ini格式文件

    功能 本脚本实现了ini文件中的查询修改指定value 百度云连接地址 链接:https://pan.baidu.com/s/12_T5yST7Y3L1H4_MkVEcvA 密码:fo5p 解压后先看 ...

  8. 【NLP】使用bert

    # 参考 https://blog.csdn.net/luoyexuge/article/details/84939755 小做改动 需要: github上下载bert的代码:https://gith ...

  9. killall命令详解

    基础命令学习目录首页 原文链接:https://blog.csdn.net/tanga842428/article/details/52474250 Linux系统中的killall命令用于杀死指定名 ...

  10. Scrum立会报告+燃尽图(十二月八日总第三十九次):制定视频方案

    此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2284 项目地址:https://git.coding.net/zhang ...