参考博客: https://www.cnblogs.com/chenbenbuyi/p/8283657.html

https://www.cnblogs.com/cnsdhzzl/p/8390514.html

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

 1 常用API

  • JAXBContext类,是应用的入口,通过该类创建序列化和反序列化对象,也即编组对象和解组对象;
  • Marshaller 编组接口,将Java对象序列化为XML数据;
  • Unmarshaller 解组接口,将XML数据反序列化为Java对象。

 2 常用注解

  • @XmlRootElement,将Java类或枚举映射成XML元素根节点,是唯一一个必须注解,name属性指定根节点名称,不指定默认为类名的小写;
  • @XmlElement,将Java类的一个属性映射为XML节点元素,name属性可自定义元素名;
  • @XmlAttribute,将Java类的一个属性映射为XML节点元素的属性,name属性可自定义属性名;
  • @XmlType,将Java类或枚举类型映射到XML模式类型,常与@XmlRootElement、@XmlAccessorType共用,propOrder属性定义字段生成的XML节点顺序;
  • @XmlAccessorType,控制字段或属性的序列化。属性XmlAccessType有4个常量值:

  FIELD表示JAXB将自动绑定Java类中的每个非静态的(static)、非瞬态的(由@XmlTransient标注)字段到XML;

  PROPERTY表示java对象中所有通过getter/setter方式绑定成属性到XML;

  PUBLIC_MEMBER表示Java对象中所有的public访问权限的成员变量和通过getter/setter方式访问的成员变量,该值为默认值;

  NONE表示Java对象的所有属性都不映射为XML的元素;

  • @XmlAccessorOrder,控制JAXB 绑定类中属性和字段的排序,有两个属性,AccessorOrder.ALPHABETICAL——对生成的XML元素按字母书序排序,XmlAccessOrder.UNDEFINED——不排序,默认为该值;
  • @XmlJavaTypeAdapter,自定义适配器(即扩展抽象类XmlAdapter并覆盖marshal()和unmarshal()方法),解决日期(Date),数字(Number)格式化问题;
  • @XmlElementWrapper ,对于数组或集合(即包含多个元素的成员变量),生成一个包装该数组或集合的XML元素(称为包装器),该注解只能用在集合上;
  • @XmlTransient ,用于标示在由Java对象映射XML时,忽略此属性,在生成的XML文件中将不出现此元素。

 3 实际应用中注意的问题

  ① 如果JavaBean中定义了有参的构造器,那么必须同时定义无参构造器,否则转XML会抛无默认构造函数的异常;

  ② 成员变量值为NULL时,将不会映射成对应的XML元素——由于基本数据类型默认值不为空,所以基本数据类型不设值也会映射成XML元素,值为默认值,所以如果模型需要基本数据,在属性定义的时候尽量使用包装类型;

  ③ @XmlAccessorType 注解中如果属性值为XmlAccessType.FIELD,则表示通过成员变量来映射,set/get方法上的映射注解就是多余的,所以如果此时set/get方法上再标注元素或者属性映射注解,将抛属性重复性异常;属性值为XmlAccessType.NONE不映射为XML元素的前提是Java字段或set/get方法上都没有映射注解;

  ④ @XmlType propOrder属性能够自定义字段的排序,该属性如果设置,要么写成{}的形式,否则在就必须将所有@XmlElement标注或者没有@XmlElement标注的但实际上会被映射为XML节点的字段添加到排序列表,不然会抛异常;如果propOrder属性设置有值,@XmlAccessorOrder注解的元素排序规则将失效;

 4 测试实例

首先给出User的JavaBean代码:

package com.test.util;

import javax.xml.bind.annotation.XmlAccessorOrder;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper; import java.util.Date;
import java.util.List; import javax.xml.bind.annotation.XmlAccessOrder; @XmlType(propOrder = {"userName","age","role","date","menu"})
@XmlRootElement(name = "user")
@XmlAccessorOrder(XmlAccessOrder.ALPHABETICAL)
public class User { private String userName;
private int age;
private String role;
private Date date;
private List<Menu> menu; public User() {
} public User(String userName, int age, String role, Date date) {
this.userName = userName;
this.role = role;
this.age = age;
this.date = date;
} public String getUserName() {
return userName;
} public void setUserName(String userName) {
this.userName = userName;
} @XmlAttribute
public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} @XmlElement
public String getRole() {
return role;
} public void setRole(String role) {
this.role = role;
} @XmlJavaTypeAdapter(DateAdapter.class)
@XmlElement
public Date getDate() {
return date;
} public void setDate(Date date) {
this.date = date;
} @XmlElementWrapper(name = "menus")
@XmlElement
public List<Menu> getMenu() {
return menu;
} public void setMenu(List<Menu> menu) {
this.menu = menu;
} @Override
public String toString() {
return "User{" +
"userName='" + userName + '\'' +
", age=" + age +
", role='" + role + '\'' +
", date='" + date + '\'' +
", menu=" + menu +
'}';
} }

在给出DateAdapter的代码:

package com.test.util;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date; import javax.xml.bind.annotation.adapters.XmlAdapter; public class DateAdapter extends XmlAdapter<String, Date> {
private static final DateFormat SDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); @Override
public Date unmarshal(String date) throws Exception {
return SDF.parse(date);
} @Override
public String marshal(Date date) throws Exception {
return SDF.format(date);
}
}

再给出Menu的代码:

package com.test.util;

import java.util.List;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement
public class Menu {
private String name;
private String id;
private List<Menu> child; public Menu() {
} public Menu(String name, String id) {
this.name = name;
this.id = id;
} @XmlAttribute
public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} @XmlAttribute
public String getId() {
return id;
} public void setId(String id) {
this.id = id;
} public List<Menu> getChild() {
return child;
} public void setChild(List<Menu> child) {
this.child = child;
} @Override
public String toString() {
return "Menu{" +
"name='" + name + '\'' +
", id='" + id + '\'' +
'}';
}
}

给出Main方法里调用解析xml的代码:

package com.test;

import java.util.List;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date; import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller; import com.test.util.Menu;
import com.test.util.User; public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub DateFormat SDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
User user = new User("UserName1", 2018, "SuperMan", new Date()); List<Menu> list1 = new ArrayList<>();
Menu menu1 = new Menu("SystemManage", "1111");
Menu child1 = new Menu("AuthoriManage", "2222");
Menu child2 = new Menu("UserManage", "3333");
list1.add(child1);
list1.add(child2);
menu1.setChild(list1); List<Menu> list2 = new ArrayList<>();
Menu menu2 = new Menu("SystemManage", "4444");
Menu child3 = new Menu("AuthoriManage", "5555");
Menu child4 = new Menu("UserManage", "6666");
list2.add(child3);
list2.add(child4);
menu2.setChild(list2); List<Menu> menus = new ArrayList<>();
menus.add(menu1);
menus.add(menu2); user.setMenu(menus); try {
JAXBContext jaxbContext = JAXBContext.newInstance(User.class);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
File file = new File("E://user.xml");
marshaller.marshal(user, file);
marshaller.marshal(user, System.out);
} catch (JAXBException e1) {
System.out.println("e1="+e1.getMessage());
} try {
File file1 = new File("E://user.xml");
JAXBContext jaxbContext = JAXBContext.newInstance(User.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
User u = (User)unmarshaller.unmarshal(file1);
System.out.println("userName="+u.getUserName()+",role="+u.getRole());
System.out.println("date="+SDF.format(u.getDate()));
List<Menu> menuss = u.getMenu();
Menu menu = null;
for(int i=0;i<menuss.size();i++){
menu = menuss.get(i);
List<Menu> menuChild = menuss.get(i).getChild();
System.out.println("id="+menu.getId()+",name="+menu.getName());
for(int j=0;j<menuChild.size();j++){
System.out.println(" child=>id="+menuChild.get(j).getId()+",name="+menuChild.get(j).getName());
}
}
} catch (JAXBException e2) {
System.out.println("e2="+e2.getMessage());
}
}

最后给出结果(控制台(Console)打印出来的结果):

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<user age="2018">
<userName>UserName1</userName>
<role>SuperMan</role>
<date>2018-09-17 15:30:47</date>
<menus>
<menu id="1111" name="SystemManage">
<child id="2222" name="AuthoriManage"/>
<child id="3333" name="UserManage"/>
</menu>
<menu id="4444" name="SystemManage">
<child id="5555" name="AuthoriManage"/>
<child id="6666" name="UserManage"/>
</menu>
</menus>
</user>
userName=UserName1,role=SuperMan
date=2018-09-17 15:30:47
id=1111,name=SystemManage
child=>id=2222,name=AuthoriManage
child=>id=3333,name=UserManage
id=4444,name=SystemManage
child=>id=5555,name=AuthoriManage
child=>id=6666,name=UserManage

待续...

JAXB介绍一的更多相关文章

  1. JAXB介绍二

    链接上一遍 JAXB介绍一 , 本节主要介绍解析xml的步骤, 下面的例子是在实际项目中运用的, 把它拿出来单独写一个java运行程序. 5. 测试实例 先给出我的代码结构图: 再给出要解析的Scri ...

  2. RestEasy简介

    RestEasy简介 RestEasy技术说明 简介 RESTEasy RESTEasy是JBoss的一个开源项目,提供各种框架帮助你构建RESTful Web Services和RESTful Ja ...

  3. spring--基本介绍

    1.1.1  Spring是什么 Spring是一个开源的轻量级Java SE(Java 标准版本)/Java EE(Java 企业版本)开发应用框架,其目的是用于简化企业级应用程序开发.应用程序是由 ...

  4. JAXB命名空间及命名空间前缀处理

    本篇介绍下JAXB进阶使用,命名空间处理 使用package-info.java添加默认命名空间在需要添加命名空间的包下面添加package-info.java文件,然后添加@XmlSchema注解, ...

  5. WebService服务调用方法介绍

    1 背景概述 由于在项目中需要多次调用webservice服务,本文主要总结了一下java调用WebService常见的6种方式,即:四种框架的五种调用方法以及使用AEAI ESB进行调用的方法. 2 ...

  6. JAX-WS:背后的技术JAXB及传递Map

    转载:http://www.programgo.com/article/98912703200/ 1.什么是JAX-WS JAX-WS (JavaTM API for XML-Based Web Se ...

  7. 【收藏用】--切勿转载Java处理XML的三种主流技术及介绍

    原帖地址 : http://www.ibm.com/developerworks/cn/xml/dm-1208gub/ XML (eXtensible Markup Language) 意为可扩展标记 ...

  8. WebService相关概念介绍

    最近重新拾起WebService,之前用过Axis2开发过服务,但是非常具体的概念还不是很清楚,在此粗略总结一下. 本文重点研究以下几个问题:     1.WebService以及相关的概念介绍    ...

  9. CXF之一 基础理论介绍

    WebService介绍   WebService让一个程序可以透明地调用互联网程序,不用管具体的实现细节.只要WebService公开了服务接口,远程客户端就可以调用服务.WebService是基于 ...

随机推荐

  1. ASCII 说明

    ASCII 说明 ASCII 码使用指定的 7 位或 8 位二进制数组合来表示 128 或 256 种可能的字符.标准 ASCII 码也叫基础ASCII码,使用 7 位二进制数来表示所有的大写和小写字 ...

  2. python+selenium UI自动化不同浏览器之间的切换

    class register(): ROBOT_LIBRARY_SCOPE = 'GLOBAL' def __init__(self): pass # m默认打开chrome def open_bro ...

  3. JAVA之J2EE学习路线

    摘自:http://blog.csdn.net/hsc456/article/details/51970559   历经2,3个月,终于学完了J2EE的方方面面,虽然还是一知半解,好歹也算是整条路都走 ...

  4. Entity Framework Code-First(9):DataAnnotations

    DataAnnotations in Code-First: EF Code-First provides a set of DataAnnotation attributes, which you ...

  5. App集成极光推送开发流程[关键步骤]

    1.客户端集成SDK 1.1初始化 JPushInterface.setDebugMode(true); // 设置开启日志,发布时请关闭日志 JPushInterface.init(this); / ...

  6. elasticsearch shard 和 replica

    (1)index包含多个shard(2)每个shard都是一个最小工作单元,承载部分数据,lucene实例,完整的建立索引和处理请求的能力(3)增减节点时,shard会自动在nodes中负载均衡(4) ...

  7. 【转】C# String 前面不足位数补零的方法

    源地址:http://www.cnblogs.com/zhangqs008/archive/2012/02/01/2341078.html

  8. 括号序列(区间dp)

    括号序列(区间dp) 输入一个长度不超过100的,由"(",")","[",")"组成的序列,请添加尽量少的括号,得到一 ...

  9. springIOC源码解析之BeanDefinition的注册

    ApplicationContext类结构 context是一个存储上下文结构的东西,里面会引用BeanFactory  BeanFactory类结构 我们从这句代码开始分析,(本文spring采用的 ...

  10. CoinEye PRIVACY POLICY

    PRIVACY POLICY First, welcome to use the app Thank you for using our products and services ("Se ...