JAXB最佳实践

时间:2023-01-31 21:52:51

JAXB主要用来实现对象和XML之间的序列化和反序列化。

本文主要总结JAXB基本使用方法和注意事项!

通过下文的XML示例内容进行JAXB的简单实践

<?xml version="1.0" encoding="UTF-8"?>
<Provinces>
<Province id="B001">
<name>北京</name>
<code>30000</code>
</Province>
<Province id="Z001">
<name>浙江</name>
<code>60000</code>
</Province>
<Province id="J001">
<name>江苏</name>
<code>90000</code>
<city citycode="90001">南京市</city>
<city citycode="90002">盐城市</city>
<city citycode="90003">扬州市</city>
<city citycode="90004">南通市</city>
</Province>
</Provinces>

citys.xml

JavaBean to XML

一、分析citys.xml,可以定义三个示例类ProvincesBean,ProvinceBean,CityBean.java

package my.jaxb.bean;

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.XmlRootElement; /**
<Provinces>
<Province id="B001">...
<Province id="B002">...
<Province id="J001">...
</Provinces>
**/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "Provinces")
public class ProvincesBean
{
@XmlElement(name = "Province")
private List<ProvinceBean> provinces = null; public List<ProvinceBean> getProvinces()
{
return provinces;
} public void setProvinces(List<ProvinceBean> provinces)
{
this.provinces = provinces;
} public String toString()
{
return "ProvincesBean ( provinces = " + this.provinces + " )";
}
}

ProvincesBean

package my.jaxb.bean;

import java.util.List;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement; /**
<Province id="J001">
<name>江苏</name>
<code>90000</code>
<city citycode="90001">南京市</city>
<city citycode="90002">盐城市</city>
<city citycode="90003">扬州市</city>
<city citycode="90004">南通市</city>
</Province>
**/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "Province")
public class ProvinceBean
{
@XmlAttribute
private String id = ""; private String name = ""; private String code = ""; @XmlElement(name = "city")
private List<CityBean> citys = null; 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 List<CityBean> getCitys()
{
return citys;
} public void setCitys(List<CityBean> citys)
{
this.citys = citys;
} public String getCode()
{
return code;
} public void setCode(String code)
{
this.code = code;
} public String toString()
{
return "ProvinceBean ( id = " + this.id + " name = " + this.name + " code = " + this.code + " citys = "
+ this.citys + " )";
}
}

ProvinceBean

package my.jaxb.bean;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlValue; /**
<city citycode="90001">南京市</city>
**/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "city")
public class CityBean
{
public CityBean()
{
} public CityBean(String cityCode, String value)
{
super();
this.cityCode = cityCode;
this.value = value;
} @XmlAttribute(name = "citycode")
private String cityCode = ""; @XmlValue
private String value = ""; public String getCityCode()
{
return cityCode;
} public void setCityCode(String cityCode)
{
this.cityCode = cityCode;
} public String getValue()
{
return value;
} public void setValue(String value)
{
this.value = value;
} public String toString()
{
return "CityBean ( cityCode = " + this.cityCode + " value = " + this.value + " )";
}
}

CityBean

二、编写序列化和反序列化的工具类-XmlUtils

package my.jaxb.comm;

import java.io.File;
import java.io.StringReader;
import java.io.StringWriter; import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller; public class XmlUtils
{
// JavaBean to XML
public static String toXML(Object obj)
{
try
{
JAXBContext context = JAXBContext.newInstance(obj.getClass()); Marshaller marshaller = context.createMarshaller();
// 设置编码格式
marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
// 是否格式化生成的XML
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
// 是否省略XML头声明信息
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, false); StringWriter writer = new StringWriter(); marshaller.marshal(obj, writer); return writer.toString();
}
catch (JAXBException e)
{
throw new RuntimeException(e.getMessage());
}
} // XML to JavaBean
public static <MY> MY fromXML(String xml, Class<MY> declareType)
{
try
{
JAXBContext context = JAXBContext.newInstance(declareType); Unmarshaller unmarshaller = context.createUnmarshaller(); Object obj = unmarshaller.unmarshal(new StringReader(xml)); return (MY) obj;
}
catch (JAXBException e)
{
throw new RuntimeException(e.getMessage());
}
} // XML(path) to JavaBean
public static <MY> MY fromXMLPath(String xmlPath, Class<MY> declareType)
{
try
{
JAXBContext context = JAXBContext.newInstance(declareType); Unmarshaller unmarshaller = context.createUnmarshaller(); Object obj = unmarshaller.unmarshal(new File(xmlPath)); return (MY) obj;
}
catch (JAXBException e)
{
throw new RuntimeException(e.getMessage());
}
} }

XmlUtils

三、编写测试代码,内部实现了JavaBean to XML和XML to JavaBean两个操作

package my.jaxb.test;

import java.util.ArrayList;
import java.util.List; import my.jaxb.bean.CityBean;
import my.jaxb.bean.ProvinceBean;
import my.jaxb.bean.ProvincesBean;
import my.jaxb.comm.XmlUtils; public class ToXMLFoo
{
public static void main(String[] args)
{
ProvincesBean provinces = new ProvincesBean();
provinces.setProvinces(getProvinces()); // JavaBean to XML
String xml = XmlUtils.toXML(provinces); System.out.println(xml); System.out.println("------------------------------"); // XML to JavaBean
provinces = XmlUtils.fromXML(xml, ProvincesBean.class); System.out.println(provinces);
} private static List<ProvinceBean> getProvinces()
{
List<ProvinceBean> provList = new ArrayList<ProvinceBean>(); ProvinceBean prov = new ProvinceBean();
prov.setId("B001");
prov.setName("北京");
prov.setCode("30000"); ProvinceBean prov2 = new ProvinceBean();
prov2.setId("Z001");
prov2.setName("浙江");
prov2.setCode("60000"); ProvinceBean prov3 = new ProvinceBean();
prov3.setId("J001");
prov3.setName("江苏");
prov3.setCode("90000"); // 单独增加城市
prov3.setCitys(getCitys()); provList.add(prov);
provList.add(prov2);
provList.add(prov3); return provList;
} private static List<CityBean> getCitys()
{
List<CityBean> cityList = new ArrayList<CityBean>(); CityBean city = new CityBean("90001", "南京市");
CityBean city2 = new CityBean("90002", "盐城市");
CityBean city3 = new CityBean("90003", "扬州市");
CityBean city4 = new CityBean("90004", "南通市");
cityList.add(city);
cityList.add(city2);
cityList.add(city3);
cityList.add(city4); return cityList;
}
}

ToXMLFoo

四、测试输出结果

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Provinces>
<Province id="B001">
<name>北京</name>
<code>30000</code>
</Province>
<Province id="Z001">
<name>浙江</name>
<code>60000</code>
</Province>
<Province id="J001">
<name>江苏</name>
<code>90000</code>
<city citycode="90001">南京市</city>
<city citycode="90002">盐城市</city>
<city citycode="90003">扬州市</city>
<city citycode="90004">南通市</city>
</Province>
</Provinces> ------------------------------
ProvincesBean ( provinces = [ProvinceBean ( id = B001 name = 北京 code = 30000 citys = null ), ProvinceBean ( id = Z001 name = 浙江 code = 60000 citys = null ), ProvinceBean ( id = J001 name = 江苏 code = 90000 citys = [CityBean ( cityCode = 90001 value = 南京市 ), CityBean ( cityCode = 90002 value = 盐城市 ), CityBean ( cityCode = 90003 value = 扬州市 ), CityBean ( cityCode = 90004 value = 南通市 )] )] )

XML to JavaBean

一、直接编写测试代码,内部实现了XML to JavaBean的操作

package my.jaxb.test;

import my.jaxb.bean.ProvincesBean;
import my.jaxb.comm.XmlUtils; public class FromXMLFoo
{
public static void main(String[] args)
{
String xmlPath = FromXMLFoo.class.getResource("/").getPath() + "citys.xml"; // XML(path) to JavaBean
ProvincesBean bean = XmlUtils.fromXMLPath(xmlPath, ProvincesBean.class); System.out.println(bean);
} }

FromXMLFoo

二、测试输出结果

ProvincesBean ( provinces = [ProvinceBean ( id = B001 name = 北京 code = 30000 citys = null ), ProvinceBean ( id = Z001 name = 浙江 code = 60000 citys = null ), ProvinceBean ( id = J001 name = 江苏 code = 90000 citys = [CityBean ( cityCode = 90001 value = 南京市 ), CityBean ( cityCode = 90002 value = 盐城市 ), CityBean ( cityCode = 90003 value = 扬州市 ), CityBean ( cityCode = 90004 value = 南通市 )] )] )

注意事项

1、要序列化的类加上@XmlRootElement注解,否则会报错!

2、JAXB序列化XML时 默认序列化getter和setter,且getter和setter必须成对出现才会被序列化。

3、属性名称,默认序列化出来的类和属性名称默认是首字母转换为小写,若需要控制属性名称需要在getter或setter上
    使用 @XmlElement(name = "Province") 指定名称,此处要注意的是@XmlElement也可以放置在getter或setter上都行,
    但只能放一个,也就是说不能同时在getter和setter或field字段三者中间任意二者上同时使用 @XmlElement注解!

4、如控制根节点名称?
Re: 使用@XmlRootElement指定name属性即可,如@XmlRootElement(name = "Provinces")。

5、怎么添加命名空间
Re: 使用@XmlRootElement(namespace="my.jaxb") 指定namespace属性,此处不做代码示例。

6、怎么精确控制每个属性名称
Re: JAXB自动转化为首字母小写会导致不可预料的属性名称出现,不嫌麻烦的话为每个属性设置@XmlElement(name=""),想省事的话使用Field字段名称即可。

7、怎么样实现序列化时使用Field字段而不是使用setter和getter
Re: 在要使用的类上面加上@XmlAccessorType(XmlAccessType.FIELD)注解,并指定为XmlAccessType.FIELD,
    这里强烈推荐使用@XmlAccessorType(XmlAccessType.FIELD)注解,因为这样你可以精确的控制每个元素的名称,
    而不需要为每个属性去设置@XmlElement(name="")注解,当然也可以在Field上使用@XmlElement注解。

8、一个元素既有属性也有文本内容情况如何配置?
Re: 如:<city citycode="90001">南京市</city> ,此时citycode字段通过@XmlAttribute(name = "citycode")控制,value字段通过@XmlValue控制即可。

JAXB最佳实践的更多相关文章

  1. ASP&period;NET跨平台最佳实践

    前言 八年的坚持敌不过领导的固执,最终还是不得不阔别已经成为我第二语言的C#,转战Java阵营.有过短暂的失落和迷茫,但技术转型真的没有想象中那么难.回头审视,其实单从语言本身来看,C#确实比Java ...

  2. 《AngularJS深度剖析与最佳实践》简介

    由于年末将至,前阵子一直忙于工作的事务,不得已暂停了微信订阅号的更新,我将会在后续的时间里尽快的继续为大家推送更多的博文.毕竟一个人的力量微薄,精力有限,希望大家能理解,仍然能一如既往的关注和支持sh ...

  3. ASP&period;NET MVC防范CSRF最佳实践

    XSS与CSRF 哈哈,有点标题党,但我保证这篇文章跟别的不太一样. 我认为,网站安全的基础有三块: 防范中间人攻击 防范XSS 防范CSRF 注意,我讲的是基础,如果更高级点的话可以考虑防范机器人刷 ...

  4. 快速web开发中的前后端框架选型最佳实践

    这个最佳实践是我目前人在做的一个站点,主要功能: oauth登录 发布文章(我称为"片段"),片段可以自定义一些和内容有关的指标,如“文中人物:12”.支持自定义排版.插图.建立相 ...

  5. Spring Batch在大型企业中的最佳实践

    在大型企业中,由于业务复杂.数据量大.数据格式不同.数据交互格式繁杂,并非所有的操作都能通过交互界面进行处理.而有一些操作需要定期读取大批量的数据,然后进行一系列的后续处理.这样的过程就是" ...

  6. Atitit&period;log日志技术的最佳实践attilax总结

    Atitit.log日志技术的最佳实践attilax总结 1. 日志的意义与作用1 1.1. 日志系统是一种不可或缺的单元测试,跟踪调试工具1 2. 俩种实现[1]日志系统作为一种服务进程存在 [2] ...

  7. PHP核心技术与最佳实践——全局浏览

    难得买到并喜欢一本好书,‘PHP核心技术与最佳实践’. 几天时间,先看了个大概,总结一下整体是什么样子的,怎么看怎么学. 1.总共14章: 2.第1.2章讲PHP的OOP: 其中第一章侧重于PHP的O ...

  8. Abp集成Swagger的最佳实践

    1.在项目中添加nuget包 Abp.Web.Api.SwaggerTool 2.在项目Abp模块的DependsOn添加AbpWebApiSwaggerToolModule Run It,启动项目, ...

  9. MySQL &&num;183&semi; 答疑解惑 &&num;183&semi; MySQL 锁问题最佳实践

    http://mysql.taobao.org/monthly/2016/03/10/ 前言 最近一段时间处理了较多锁的问题,包括锁等待导致业务连接堆积或超时,死锁导致业务失败等,这类问题对业务可能会 ...

随机推荐

  1. JavaScript基本语法(二)

    上篇博文写到JavaScript的数据类型.JavaScript包括了字符串(String).数字(Number).布尔(Boolean).数组(Array).对象(Object).空(Null).未 ...

  2. 一、XML语法

    xml声明xml指令:<? ?>xml编码与乱码xml元素(标签)CDATA区空格与换行会被认为是标签的内容xml-stylesheet指令解析xml内容 <?xml version ...

  3. 配置redis开机自启动和监听

    redis安装好后,每次手动启动很不方便,配置开机自启动. 方法一:设置启动命令到/etc/rc.d/rc.local rc.local文件是系统全局脚本文件,会在其他开机进程脚本文件执行完毕后执行该 ...

  4. POJ - 2828

    题意 输入队伍长度n 接下来n行,a,b 表示b插在队伍的a处 求队伍最后的情况 题解 刚开始并不知道要用线段树,经大佬点悟,发现最后插入的位置就是对应的a.所以可以从后往前依次插入,每次的位置pos ...

  5. 马尔科夫随机场模型(MRF-Markov Random Field)

    原文: http://blog.sina.com.cn/s/blog_92c398b00102vs3q.html 马尔科夫过程​ 隐马尔科夫过程​​ 与马尔科夫相比,隐马尔可夫模型则是双重随机过程,不 ...

  6. 不改源代码,修改服务器配置,解决全局Get中文乱码问题

  7. SpringMVC整个执行流程

    在SSM (或SSH) 框架整合使用后,基本骨架看上去还是MVC的结构. MyBatis整合一些数据封装方法节省了DAO层的代码量, Spring提供了AOP,IoC( DI 具体实现 ). 而Spr ...

  8. Servlet与JSP九大内置对象的对应关系

    JSP对象 Servlet中怎样获得 out resp.getWriter request service方法中的req参数 response service方法中的resp参数 session re ...

  9. Spring MVC 方法注解拦截器

    应用场景,在方法级别对本次调用进行鉴权,如api接口中有个用户唯一标示accessToken,对于有accessToken的每次请求可以在方法加一个拦截器,获得本次请求的用户,存放到request或者 ...

  10. Java循环结构 - for&comma; while 及 do&period;&period;&period;while

    Java循环结构 - for, while 及 do...while 顺序结构的程序语句只能被执行一次.如果您想要同样的操作执行多次,,就需要使用循环结构. Java中有三种主要的循环结构: whil ...