JAXB读写xml
一、注解
在Java模型中的创建与 xml 文件对应的节点和属性需要用注解来表示
@XmlRootElement
作用:将一个Java类映射为一段XML的根节点参数:
name 定义这个根节点的名称
namespace 定义这个根节点命名空间
@XmlAccessorType
作用:定义映射这个类中的何种类型需要映射到XML。
可接收四个参数,分别是:
XmlAccessType.FIELD:表示将这个类中的 非静态(static)、非序列化(transient)属性映射到xml,有无get/set方法均可
XmlAccessType.PROPERTY:使用 set/get 方法来序列化属性或者元素(get方法可不需注解自动映射)——说明:通过get方法映射到xml,get方法上是否添加注解都可,但是不能在属性上添加注解
XmlAccessType.PUBLIC_MEMBER:将这个类中的所有public的field(字段)或property(get/set对)同时映射到XML(默认注解),该注解包含了XmlAccessType.FIELD和XmlAccessType.PROPERTY两个注解,所以注意不要对同一个字段添加两次注解
XmlAccessType.NONE:不映射
补充说明:
@XmlAccessorType的默认访问级别是 XmlAccessType.PUBLIC_MEMBER,因此,如果java对象中的private成员变量设置了public权限的 getter/setter方法,就不要在private变量上使用@XmlElement和@XmlAttribute注解,否则在由java对象生成 xml时会报同一个属性在java类里存在两次的错误。
同理,如果@XmlAccessorType的访问权限为XmlAccessType.NONE, 如果在java的成员变量上使用了@XmlElement或@XmlAttribute注解,这些成员变量依然可以映射到xml文件。
@XmlElements
// 表示或的关系,list集合中内容可以为以下两种类型
@XmlElements({
@XmlElement(name = "Person", type = Person.class),
@XmlElement(name = "String", type = String.class)
})
private List list;
补充说明:如果List使用泛型,则List集合中只能含有一种数据类型,此时使用该注解无用。
@XmlElement
作用:指定一个字段或get/set方法映射到XML的节点。如,当一个类的XmlAccessorType 被标注为PROPERTY时,在某一个没有get/set方法的字段上标注此注解,即可将该字段映射到XML。
参数:
defaultValue 指定节点默认值
name 指定节点名称
namespace 指定节点命名空间
type 定义该字段或属性的关联类型
required 是否必须(默认为false)
nillable 该字段是否包含 nillable="true" 属性(默认为false)
@XmlAttribute
作用:指定一个字段或get/set方法映射到XML的属性(区别@XmlElement——节点)。
参数:
Name 指定属性名称
namespace 指定属性命名空间
required 是否必须(默认为false)
@XmlTransient
作用:定义某一字段或属性不需要被映射为XML。
如,当一个类的XmlAccessorType 被标注为PROPERTY时,在某一get/set方法的字段上标注此注解,那么该属性则不会被映射。
@XmlType
作用:定义映射的一些相关规则
参数:
propOrder 指定映射XML时的节点顺序
factoryClass 指定UnMarshal时生成映射类实例所需的工厂类,默认为这个类本身
factoryMethod 指定工厂类的工厂方法
name 定义XML Schema中type的名称
namespace 指定Schema中的命名空间
@XmlElementWrapper
作用:为数组元素或集合元素定义一个父节点。
如,类中有一元素为List items,若不加此注解,该元素将被映射为
<items>...</items>
<items>...</items>
这种形式,此注解可将这个元素进行包装,如:
@XmlElementWrapper(name="items")
@XmlElement(name="item")
public List items;
将会生成这样的XML样式:
<items>
<item>...</item>
<item>...</item>
</items>
@XmlJavaTypeAdapter
作用:自定义某一字段或属性映射到XML的适配器。
如,类中包含一个接口,我们可以定义一个适配器(继承自 javax.xml.bind.annotation.adapters.XmlAdapter类),指定这个接口如何映射到XML。
@XmlSchema
作用:配置整个包的namespace,这个注解需放在package-info.java文件中
二、代码实例
/**
* @Title: Menus.java
* @Package cn.com.kamfu.base
* @Description: TODO(用一句话描述该文件做什么)
* @author: liandy
* @date: 2019年7月17日 上午1:41:42
* @version V1.0
*/
package cn.com.kamfu.lang; import java.util.List; import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSeeAlso; /**
* @ClassName: Menus
* @Description:TODO(这里用一句话描述这个类的作用)
* @author: liandy
* @date: 2019年7月17日 上午1:41:42
*
*/
@XmlRootElement(name = "items")
@XmlAccessorType(XmlAccessType.FIELD)
public class ListObj<T> {
@XmlElement(name = "item")
private List<T> item; public List<T> getItem() {
return item;
} public void setItem(List<T> item) {
this.item = item;
} }
ListObj
/**
* @Title: XmlList.java
* @Package cn.com.kamfu.base
* @Description: TODO(用一句话描述该文件做什么)
* @author: liandy
* @date: 2019年7月17日 上午12:16:58
* @version V1.0
*/
package cn.com.kamfu.lang; import java.util.List; import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement; /**
* @ClassName: XmlList
* @Description:TODO(这里用一句话描述这个类的作用)
* @author: liandy
* @date: 2019年7月17日 上午12:16:58
*
*/ @XmlAccessorType(XmlAccessType.FIELD)
public class Menu {
@XmlElement(name = "id")
private String id;
@XmlElement(name = "name")
private String name;
@XmlElement(name = "url")
private String url;
@XmlElementWrapper(name = "items")
private List<Menu> item; public Menu() {
super();
} public Menu(String id, String name, String url) {
super();
this.id = id;
this.name = name;
this.url = url;
} public String getId() {
return id;
} public void setId(String id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getUrl() {
return url;
} public void setUrl(String url) {
this.url = url;
} public List<Menu> getMenu() {
return item;
} public void setMenu(List<Menu> menu) {
this.item = menu;
} }
Menu
package cn.com.kamfu.util; import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List; import javax.enterprise.inject.New;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller; import org.dom4j.jaxb.JAXBReader; import cn.com.kamfu.lang.ListObj;
import cn.com.kamfu.lang.Menu; public class JaxbXmlUtil { /**
* @Title: marshallerByJaxb
* @Description: TODO(这里用一句话描述这个方法的作用)
* @param: @param path
* @param: @param object
* @param: @param classesToBeBound
* @return: void
* @throws
*/
public static void marshallerByJaxb(String path,Object object,Class... classesToBeBound) {
try {
JAXBContext jc = JAXBContext.newInstance(classesToBeBound); Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");// 编码格式
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);// 是否格式化生成的xml串
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, false);// 是否省略xml头声明信息 File file = new File(path);
if (!file.exists()) {
file.createNewFile();
}
marshaller.marshal(object, file);
} catch (JAXBException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} public static Object unmarshallerByJaxb(String path,Object object,Class... classesToBeBound) {
try {
JAXBContext jc = JAXBContext.newInstance(classesToBeBound); Unmarshaller unmarshaller = jc.createUnmarshaller(); File file = new File(path);
if (!file.exists()) {
throw new FileNotFoundException("Can not load xml file!");
} return unmarshaller.unmarshal(file);
} catch (JAXBException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return null;
}
public static void main(String[] args) throws JAXBException {
ListObj<Menu> listObj=new ListObj<Menu>();
List<Menu> menuallList=new ArrayList<Menu>(); Menu menu = new Menu("1","用户管理","");
Menu item1=new Menu("2","新增用户","");
Menu item2=new Menu("2","删除用户","");
Menu item3=new Menu("2","修改用户","");
Menu item4=new Menu("2","查询用户",""); List<Menu> list=new ArrayList<Menu>();
list.add(item1);list.add(item2);list.add(item3);list.add(item4);
menu.setMenu(list);
menuallList.add(menu);menuallList.add(menu);menuallList.add(menu);
listObj.setItem(menuallList);
URL url=JAXBReader.class.getClassLoader().getResource("");
String path=url.getFile().toString()+"config/menu.xml";
JaxbXmlUtil.marshallerByJaxb(path,listObj, listObj.getClass(),menu.getClass());
ListObj<Menu> ssListObj=(ListObj<Menu>) JaxbXmlUtil.unmarshallerByJaxb(path,new ListObj<Menu>(),listObj.getClass(),menu.getClass());
System.out.println(1);
}
}
JaxbXmlUtil
三、List、Map集合类型说明
集合必须封装在对象内部才能使用jaxb转为xml,不能直接将集合直接转为xml
3.1 List
List集合或数组只要封装到对象内部,使用@XMLElementWrapper注解
说明:当对象内部只有一个List集合的属性时,可以不加@XMLElementWrapper注解增加一层节点,直接将List结合内的对象作为根节点下的二级节点即可。
3.2 Map
如:Map<String, Person>集合,Person为自定义的一个对象
1.创建一个新对象(如:AllPerson)作为中转对象,该对象内含有两个属性,分别是String和Person类型的(前者为Map的key,后者为Map的value);
2.使用@XMLJavaTypeAdapter注解将Map<String, Person>转为AllPerson[],数组的大小与Map的大小相同;
总结:XmlAdapter中的两个方法各有用处,注意不要漏掉
Object->xml时
Map<String, Person>—转为—> AllPerson[](AllPerson对象中包含String, Person)
Xml->Object时
AllPerson[](AllPerson对象中包含String, Person)—转为—> Map<String, Person>
JAXB读写xml的更多相关文章
- 使用JAXB读写xml
1.注解 在Java模型中的创建与 xml 文件对应的节点和属性需要用注解来表示 @XmlRootElement 作用:将一个Java类映射为一段XML的根节点参数: name 定义这个根节点 ...
- C#读写xml文件的常用方法
已知有一个XML文件(bookshop.xml)如下: <?xml version="1.0" encoding="gb2312" ?> <b ...
- PHP读写XML文件的四种方法
PHP对XML文件进行读写操作的方法一共有四种,分别是:字符串方式直接读写.DOMDocument读写. XMLWrite写和XMLReader读.SimpleXML读写,本文将依次对这四种方法进行介 ...
- 在.net中序列化读写xml方法的总结
在.net中序列化读写xml方法的总结 阅读目录 开始 最简单的使用XML的方法 类型定义与XML结构的映射 使用 XmlElement 使用 XmlAttribute 使用 InnerText 重命 ...
- Linux Shell脚本读写XML文件
在Linux下如何用Shell脚本读写XML?现有一个config.xml <?xml version="1.0" encoding="UTF-8"?&g ...
- ADO.NET 快速入门(六):读写 XML
ADO.NET 和 DataSet 可以读写 XML Schema 和 XML.获取更多信息,请参考 How do I...Use XML and the DataSet? DataSet 的 S ...
- C#_在.net中序列化读写xml方法的总结
阅读目录 开始 最简单的使用XML的方法 类型定义与XML结构的映射 使用 XmlElement 使用 XmlAttribute 使用 InnerText 重命名节点名称 列表和数组的序列化 列表和数 ...
- Java 读写XML文件 API--org.dom4j
om4j是一个Java的XML API,类似于jdom,用来读写XML文件的.dom4j是一个十分优秀的JavaXML API,具有性能优异.功能强大和极其易使用的特点,同时它也是一个开放源代码的软件 ...
- Fixflow引擎解析(三)(模型) - 创建EMF模型来读写XML文件
Fixflow引擎解析(四)(模型) - 通过EMF扩展BPMN2.0元素 Fixflow引擎解析(三)(模型) - 创建EMF模型来读写XML文件 Fixflow引擎解析(二)(模型) - BPMN ...
随机推荐
- MyEclipse配置maven创建项目教程入门
Maven简介:Maven是一个项目管理工具,主要用于Java平台的项目构建.依赖管理和项目生命周期管理. 下载Maven: https://maven.apache.org/download.cgi ...
- java23种设计模式(一)-- 工厂模式、抽象工厂模式和单例模式
一.工厂模式 1.定义统一的接口,并在接口中定义要实现的抽象方法. 2.创建接口的具体实现类,并实现抽象方法. 3.创建一个工厂类,根据传递的参数,生成具体的实现类对象,执行具体的方法. 优点: 1. ...
- 使用egg.js和egg-sequelize连接mysql
1.通过 egg-init 初始化一个项目: egg-init --type=simple --dir=sequelize-projectcd sequelize-projectnpm i 2.安装并 ...
- TCP三次握手过程和四次释放
TCP是面向连接的协议 客户端发送 SYN包,和随机数SEQ.此时客户端是SYN_SENT状态. 服务器返回SYN+ACK,和随机数SEQ, rwnd是告诉客户端我可以接收多少字节.此时服务器端是SY ...
- Python--同步锁(互斥锁)、死锁(状态)、递归锁、信号量、Event对象
同步锁/互斥锁 (Lock) import time import threading def sub(): global num #在每个线程中都获取这个全局变量 #num-=1 temp=num ...
- oracle创建用户ORA-01045:user lacks CREATE SESSION privilege;
conn internal/oracle grant user aaaa identified by aaaa; conn aaaa/aaaa 会报错: SQL>conn aaaa/aaaa 会 ...
- bzoj 2013
http://www.lydsy.com/JudgeOnline/problem.php?id=2013 最初看这个题的时候,以为神题不可做,然后去找yzjc..然后做法过于简单了(' ' ...
- POJ 2387 Til the Cows Come Home (dijkstra模板题)
Description Bessie is out in the field and wants to get back to the barn to get as much sleep as pos ...
- hdu 4705 Y (树形dp)
Description Input 4 1 2 1 3 1 4 题目的意思是给你一棵树,让你找到所有不在一条路径上的三个点的情况个数.乍一看正向处理比较麻烦,我们从反方向考虑,如果是取在一条路径上的3 ...
- AcWing 208. 开关问题 (高斯消元+状压)打卡
有N个相同的开关,每个开关都与某些开关有着联系,每当你打开或者关闭某个开关的时候,其他的与此开关相关联的开关也会相应地发生变化,即这些相联系的开关的状态如果原来为开就变为关,如果为关就变为开. 你的目 ...