JAXB java类与xml互转
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互转的更多相关文章
- JAXB—Java类与XML文件之间转换
JAXB-Java类与XML文件之间转换 简介 JAXB(Java Architecture for XML Binding) 是一个业界的标准,是一项可以根据XML Schema产生 ...
- JAVA bean与XML互转的利器---XStream
最近在项目中遇到了JAVA bean 和XML互转的需求, 本来准备循规蹈矩使用dom4j忽然想起来之前曾接触过的XStream, 一番研究豁然开朗,利器啊利器, 下来就XStream的一些用法与大家 ...
- 使用JDK自带的JAXB进行类和xml的互转
Classroom.java public class Classroom { private int id; private String name; private int grade; publ ...
- 简单Java类与XML之间的转换
需要的jar包:xmlpull_1_0_5.jar,xstream-1.4.1.jar) 1.工具类XstreamUtil package com.learn.util; import com.tho ...
- JAXB(Java Architecture for XML Binding)
marshal(Java对象转化成XML) import javax.xml.bind.annotation.XmlRootElement; //指定根元素,其他属性默认为根元素的子元素 @XmlRo ...
- Java Jaxb JavaBean与XML互转
1.Jaxb - Java Arcitecture for XML Binding 是业界的一个标准,是一项能够依据XML Schema产生Java类的技术. Jaxb2.0是Jdk1.6的组成部分. ...
- JAXB 实现java对象与xml之间互相转换
首先熟悉一下JAXB实现对象与xml互转时常用的一些注解使用: 1.@XmlRootElement,用于类级别的注解,对应xml的跟元素.通过name属性定义这个根节点的名称. 2.@XmlAcces ...
- jaxb 专题一(JAXB 实现java对象与xml之间互相转换)
首先熟悉一下JAXB实现对象与xml互转时常用的一些注解使用: 1.@XmlRootElement,用于类级别的注解,对应xml的跟元素.通过name属性定义这个根节点的名称. 2.@XmlAcces ...
- java生成解析xml的另外两种方法JAXB
JAXB(Java Architecture for XML Binding) 是一个业界的标准,是一项可以根据XML Schema产生Java类的技术.该过程中,JAXB也提供了将XML实例文档反 ...
随机推荐
- Post请求和Get请求;@RequestBody和@RequestParam
1.@RequestBody用于Post请求,接收json数据,例如:@RequestBody User user 例如:@RequestBody Map map .不要用于Get请求. 2.@Req ...
- bootstrap switch样式修改与多列等间距布局
先以一张图开启今天的随笔 今天实习遇到了switch按钮,小姐姐说用插件bootstrap switch来写,我第一次用这个插件,首先在引入方面就遇到了很多坑,先来总结一下bootstrap swit ...
- iOS分类Category探索
什么是Category? Category是Objective-C 2.0之后添加的语言特性,Category的主要作用是为已经存在的类添加方法,一般称为分类,文件名格式是"NSObject ...
- v-if、v-show 指令
HTML部分: <div id="app"> <button type="button" @click="flag=!flag&qu ...
- php从入门到放弃系列-02.php基础语法
php从入门到放弃系列-02.php基础语法 一.学习语法,从hello world开始 PHP(全称:PHP:Hypertext Preprocessor,即"PHP:超文本预处理器&qu ...
- 高可用OpenStack(Queen版)集群-4.keystone集群
参考文档: Install-guide:https://docs.openstack.org/install-guide/ OpenStack High Availability Guide:http ...
- 从零开始的Python学习Episode 17——序列化
序列化 我们把对象(变量)从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling,在其他语 言中也被称之为serialization,marshalling,flattenin ...
- 持续更新 | 想不到的key
前言 开坑写一些我认为比较巧妙的东西想不到的东西 正文 判断回文串的时候 考虑一下枚举中心位往两边扩展 最大子矩阵与单调栈 遇难则反系列 算合法可以转换成算不合法.同理,不合法转换成合法计算有时也会简 ...
- 微软职位内部推荐-Software Engineer II_VS
微软近期Open的职位: Job Title: Software Engineer II Division: Visual Studio China – Developer Division Work ...
- Java 面试 --- 3
上一篇,我们给出了大概35个题目,都是基础知识,有童鞋反映题目过时了,其实不然,这些是基础中的基础,但是也是必不可少的,面试题目中还是有一些基础题目的,我们本着先易后难的原则,逐渐给出不同级别的题目, ...