一、前言

最近有个需求,需要进行xml 与 bean 的相互转化。

使用 JAXB 可完成这个需求。

二、概述

JAXB(Java Architecture for XML Binding) 是一个业界的标准,是一项可以根据XML Schema产生Java类的技术。该过程中,JAXB也提供了将XML实例文档反向生成Java对象树的方法,并能将Java对象树的内容重新写到 XML实例文档。

也就是说,使用JAXB 可以很方便地进行 xml 与 java bean 的互转。

三、基础知识

1.常用类

(1)JAXBContext类,是应用的入口,用于管理XML/Java绑定信息。
(2)Marshaller接口,将Java对象序列化为XML数据。
(3)Unmarshaller接口,将XML数据反序列化为Java对象。

2.常用注解

序号 注解 作用
1 @XmlType 将Java类或枚举类型映射到XML模式类型
2 @XmlAccessorType(XmlAccessType.FIELD) 控制字段或属性的序列化。FIELD表示JAXB将自动绑定Java类中的每个非静态的(static)、非瞬态的(由@XmlTransient标 注)字段到XML。其他值还有XmlAccessType.PROPERTY和XmlAccessType.NONE
3 @XmlAccessorOrder 控制JAXB 绑定类中属性和字段的排序
4 @XmlJavaTypeAdapter 使用定制的适配器(即扩展抽象类XmlAdapter并覆盖marshal()和unmarshal()方法),以序列化Java类为XML
5 @XmlElementWrapper 使用定制的适配器(即扩展抽象类XmlAdapter并覆盖marshal()和unmarshal()方法),以序列化Java类为XML
6 @XmlRootElement 将Java类或枚举类型映射到XML元素
7 @XmlElement 将Java类的一个属性映射到与属性同名的一个XML元素
8 @XmlAttribute 将Java类的一个属性映射到与属性同名的一个XML属性。
9 @XmlValue 将Java类的一个属性映射为 当前节点的文本值

注解都在 javax.xml.bind.annotation 包下,部分注解如下:

四、使用实例

1.依赖

JDK自带 jaxb ,因此无需安装依赖。

不过demo中使用了lombok,junit,需要自行安装这两个依赖。

2. 工具类

JaxbXmlUtil

  1. package com.ray.scriptenginestudy.xml.parser.util;
  2.  
  3. import javax.xml.bind.JAXBContext;
  4. import javax.xml.bind.Marshaller;
  5. import javax.xml.bind.Unmarshaller;
  6. import java.io.StringReader;
  7. import java.io.StringWriter;
  8.  
  9. /**
  10. *
  11. */
  12. public class JaxbXmlUtil {
  13.  
  14. /**
  15. * JavaBean转换成xml
  16. * * 默认编码UTF-8
  17. *
  18. * @param obj
  19. * @return
  20. */
  21. public static String convertToXml(Object obj) {
  22. return convertToXml(obj, "UTF-8");
  23. }
  24.  
  25. /**
  26. * JavaBean转换成xml
  27. * @param obj
  28. * @param encoding
  29. * @return
  30. */
  31. public static String convertToXml(Object obj, String encoding) {
  32. String result = null;
  33. try {
  34. JAXBContext context = JAXBContext.newInstance(obj.getClass());
  35. Marshaller marshaller = context.createMarshaller();
  36. marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
  37. marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding);
  38.  
  39. StringWriter writer = new StringWriter();
  40. marshaller.marshal(obj, writer);
  41. result = writer.toString();
  42. } catch (Exception e) {
  43. e.printStackTrace();
  44. }
  45.  
  46. return result;
  47. }
  48.  
  49. /**
  50. * xml转换成JavaBean
  51. * @param xml
  52. * @param c
  53. * @return
  54. */
  55. @SuppressWarnings("unchecked")
  56. public static <T> T converyToJavaBean(String xml, Class<T> c) {
  57. T t = null;
  58. try {
  59. JAXBContext context = JAXBContext.newInstance(c);
  60. Unmarshaller unmarshaller = context.createUnmarshaller();
  61. t = (T) unmarshaller.unmarshal(new StringReader(xml));
  62. } catch (Exception e) {
  63. e.printStackTrace();
  64. }
  65.  
  66. return t;
  67. }
  68. }

3.country.xml

  1. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  2. <country>
  3. <country_name>中国</country_name>
  4. <provinces>
  5. <province>
  6. <province_name>江苏省</province_name>
  7. <prov_city>南京市</prov_city>
  8. </province>
  9. <province>
  10. <province_name>浙江省</province_name>
  11. <prov_city>杭州市</prov_city>
  12. </province>
  13. </provinces>
  14. </country>

下面我将要使用 jaxb 来将此xml文件转换成实体类。

4.实体类

(1)Country

  1. package com.ray.scriptenginestudy.xml.parser.demo;
  2.  
  3. import lombok.Data;
  4.  
  5. import javax.xml.bind.annotation.*;
  6. import java.util.List;
  7.  
  8. /**
  9. * @author : shira
  10. * @date : 2018/8/2
  11. * @time : 15:15
  12. * @desc :
  13. **/
  14. @XmlAccessorType(XmlAccessType.FIELD)
  15. @XmlRootElement(name = "country")
  16. @XmlType(propOrder = { "name", "president","provinceList" })
  17. @Data
  18. public class Country {
  19.  
  20. /** 节点 **/
  21. @XmlElement(name = "country_name")
  22. private String name;
  23.  
  24. @XmlElement(name = "president")
  25. private User president;
  26.  
  27. /** 包装节点 **/
  28. @XmlElementWrapper(name = "provinces")
  29. @XmlElement(name = "province")
  30. private List<Province> provinceList;
  31.  
  32. }

(2)User

  1. package com.ray.scriptenginestudy.xml.parser.demo;
  2.  
  3. import lombok.Data;
  4.  
  5. import javax.xml.bind.annotation.*;
  6.  
  7. /**
  8. * @author : shira
  9. * @date : 2018/8/2
  10. * @time : 17:32
  11. * @desc :
  12. **/
  13. @XmlAccessorType(XmlAccessType.FIELD)
  14. @XmlType(propOrder = { "name" })
  15. @Data
  16. public class User {
  17.  
  18. /** 节点的属性 **/
  19. @XmlAttribute
  20. private String name;
  21.  
  22. /** 节点的文本值 **/
  23. @XmlValue
  24. private String text;
  25.  
  26. }

(3)Province

  1. package com.ray.scriptenginestudy.xml.parser.demo;
  2.  
  3. import lombok.Data;
  4.  
  5. import javax.xml.bind.annotation.XmlAccessType;
  6. import javax.xml.bind.annotation.XmlAccessorType;
  7. import javax.xml.bind.annotation.XmlElement;
  8. import javax.xml.bind.annotation.XmlType;
  9.  
  10. /**
  11. * @author : shira
  12. * @date : 2018/8/2
  13. * @time : 15:17
  14. * @desc :
  15. **/
  16. @XmlAccessorType(XmlAccessType.FIELD)
  17. @XmlType(propOrder = { "name", "provCity" })
  18. @Data
  19. public class Province {
  20.  
  21. @XmlElement(name = "province_name")
  22. private String name;
  23.  
  24. @XmlElement(name = "prov_city")
  25. private String provCity;
  26. }

5.测试类

JaxbXmlUtilTest

  1. package com.ray.scriptenginestudy.xml.parser.demo;
  2.  
  3. import com.ray.scriptenginestudy.xml.parser.util.JaxbXmlUtil;
  4. import lombok.extern.slf4j.Slf4j;
  5. import org.junit.Test;
  6.  
  7. import java.io.IOException;
  8. import java.nio.file.Files;
  9. import java.nio.file.Paths;
  10. import java.util.ArrayList;
  11. import java.util.List;
  12.  
  13. /**
  14. * @author : shira
  15. * @date : 2018/8/2
  16. * @time : 15:20
  17. * @desc :
  18. **/
  19. @Slf4j
  20. public class JaxbXmlUtilTest {
  21.  
  22. /**
  23. * 1.将实体类转为xml
  24. */
  25. @Test
  26. public void testBean2Xml() {
  27. //1.创建实体类
  28. Country country = new Country();
  29. country.setName("中国");
  30.  
  31. User user = new User();
  32. user.setName("习大大");
  33. user.setText("很有优秀的主席");
  34. country.setPresident(user);
  35.  
  36. List<Province> list = new ArrayList<Province>();
  37. Province province = new Province();
  38. province.setName("江苏省");
  39. province.setProvCity("南京市");
  40. Province province2 = new Province();
  41. province2.setName("浙江省");
  42. province2.setProvCity("杭州市");
  43. list.add(province);
  44. list.add(province2);
  45.  
  46. country.setProvinceList(list);
  47.  
  48. //2.将实体类转为xml
  49. String str = JaxbXmlUtil.convertToXml(country);
  50. log.info(str);
  51. }
  52.  
  53. /**
  54. * 2.将xml转为实体类
  55. */
  56. @Test
  57. public void testXml2Bean() throws IOException {
  58. //1.读取xml
  59. byte[] bytes = Files.readAllBytes(Paths.get("D:\\workspace-study-trial\\script-engine-study\\src\\test\\resources\\demo.xml"));
  60. String xml= new String(bytes);
  61. log.info("xml:{}",xml);
  62.  
  63. //2.将xml转为实体类
  64. Country country = JaxbXmlUtil.converyToJavaBean(xml, Country.class);
  65. log.info("country:{}",country);
  66. }
  67. }

五、JAXB关键类

1.JAXBContext

此类主要有以下几个作用:

(1)创建 JAXBContext 的实例

(2)创建 Unmarshaller   ,用于将 xml 转换成 实体类

(3)创建 Marshaller ,用于将 实体类转换成 xml

(4)生成Schema文件

JAXBContext  的继承结构如下,实际执行者为 JAXBContextImpl

2.Unmarshaller

  1. xml转为实体类

3.Marshaller

将实体类转换为xml

六、与脚本引擎结合

接下来实现:在xml中写js脚本,然后用java解析xml,然后执行脚本。

1.server_script.xml

  1. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  2. <init-procedure>
  3. <server-script><![CDATA[
  4.  
  5. function testScript() {
  6. print("1111111");
  7. }
  8.  
  9. testScript();
  10.  
  11. ]]></server-script>
  12.  
  13. </init-procedure>

2.实体类

InitProcedure

  1. package com.ray.scriptenginestudy.xml.parser.server.script;
  2.  
  3. import lombok.Data;
  4.  
  5. import javax.xml.bind.annotation.*;
  6.  
  7. /**
  8. * @author : shira
  9. * @date : 2018/8/2
  10. * @time : 16:21
  11. * @desc :
  12. **/
  13. @XmlAccessorType(XmlAccessType.FIELD)
  14. @XmlRootElement(name = "init-procedure")
  15. @XmlType(propOrder = { "serverScript" })
  16. @Data
  17. public class InitProcedure {
  18.  
  19. @XmlElement(name = "server-script")
  20. private ServerScript serverScript;
  21.  
  22. }

ServerScript

  1. package com.ray.scriptenginestudy.xml.parser.server.script;
  2.  
  3. import lombok.Data;
  4.  
  5. import javax.xml.bind.annotation.*;
  6.  
  7. /**
  8. * @author : shira
  9. * @date : 2018/8/2
  10. * @time : 16:33
  11. * @desc :
  12. **/
  13. @XmlAccessorType(XmlAccessType.FIELD)
  14. @XmlType(propOrder = { "jsimport" })
  15. @Data
  16. public class ServerScript {
  17.  
  18. @XmlAttribute
  19. private String jsimport;
  20.  
  21. @XmlValue
  22. private String cdata;
  23.  
  24. }

3.JAXB工具类

同上

4.测试类

ServerScriptTest

  1. package com.ray.scriptenginestudy;
  2.  
  3. import com.ray.scriptenginestudy.xml.parser.server.script.InitProcedure;
  4. import com.ray.scriptenginestudy.xml.parser.util.JaxbXmlUtil;
  5. import lombok.extern.slf4j.Slf4j;
  6. import org.junit.Test;
  7.  
  8. import javax.script.ScriptEngine;
  9. import javax.script.ScriptEngineManager;
  10. import javax.script.ScriptException;
  11. import java.io.IOException;
  12. import java.nio.file.Files;
  13. import java.nio.file.Paths;
  14.  
  15. /**
  16. * @author : shira
  17. * @date : 2018/8/2
  18. * @time : 16:23
  19. * @desc :
  20. **/
  21. @Slf4j
  22. public class ServerScriptTest {
  23.  
  24. @Test
  25. public void testServerScript() throws IOException, ScriptException {
  26. //1.解析xml
  27. byte[] bytes = Files.readAllBytes(Paths.get("D:\\workspace-study-trial\\script-engine-study\\src\\test\\resources\\server_script.xml"));
  28. String xml= new String(bytes);
  29. InitProcedure initProcedure = JaxbXmlUtil.converyToJavaBean(xml, InitProcedure.class);
  30.  
  31. //2.准备js脚本
  32. String script=initProcedure.getServerScript().getCdata();
  33. log.info("script:{}",script);
  34.  
  35. //3.创建引擎
  36. ScriptEngineManager manager = new ScriptEngineManager();
  37. ScriptEngine engine = manager.getEngineByName("JavaScript");
  38.  
  39. //4.执行脚本
  40. engine.eval(script);
  41.  
  42. }
  43.  
  44. }

七、参考资料

1.JAXB应用实例

2.Jaxb2 实现Bean与xml互转

3.Jaxb2 实现JavaBean与xml互转

Java_数据交换_JAXB_用法入门的更多相关文章

  1. Java_数据交换_fastJSON_01_用法入门

    一.用法 1.序列化—将Object转为Json对象 Object data=JSON.toJSON( MyObject ); 注:本文的Object可以是Map.List.javaBean等 需求: ...

  2. Java_数据交换_Jackson_用法入门

    一.用法 二.参考资料 1.官方 1.Java下利用Jackson进行JSON解析和序列化 2.

  3. Java_脚本引擎_01_用法入门

    一.前言 最近有个需求,需要在js中调用java,这样能避免更新java,从而实现代码的热更新. 于是想到用 Nashorn JavaScript 引擎. 二.概述 通过 JDK 8 的 Nashor ...

  4. Java_数据交换_Gson_00_资源帖

    1.Gson将字符串转换成JsonObject和JsonArray 2.Gson 解析教程 3.Gson全解析(上)-Gson基础

  5. Java_数据交换_dom4j_01_解析xml

    1.说明 详细原理以后再研究,先将例子存着 2.代码 2.1 xml内容 <?xml version="1.0" encoding="UTF-8"?> ...

  6. 你好,C++(26)如何与函数内部进行数据交换?5.1.3 函数参数的传递

    5.1.3  函数参数的传递 我们知道,函数是用来完成某个功能的相对独立的一段代码.函数在完成这个功能的时候,往往需要外部数据的支持,这时就需要在调用这个函数时向它传递所需要的数据它才能完成这个功能获 ...

  7. JSON的基本结构和数据交换原理

    0.补充的写在前面的话 2017.03.29 补充内容 最近看到这篇博客的阅读量,想来应该是有部分网友来过想要了解JSON的基本概念,这篇博文写得可能不是那么好,所以现在再补充贴一位老师的文章,希望能 ...

  8. (77)Wangdao.com第十五天_JavaScript 用于数据交换的文本格式 JSON 对象

    JSON 对象 JSON (JavaScript Object Notation 的缩写) 也是一种数据,是 JavaScript 的原生对象,用来处理 JSON 格式数据.它有两个静态方法:JSON ...

  9. Unit02: JSON 、 使用JSON实现数据交换 、 jQuery对AJAX的支持,编码问题

    Unit02: JSON . 使用JSON实现数据交换 . jQuery对AJAX的支持 1. 编码问题 (1)发送get请求 为什么会产生乱码? ie浏览器提供的ajax对象,对中文会使用gbk来编 ...

随机推荐

  1. mysql大致学习路径

  2. app开发团队人员构成怎么分配?国内著名的app开发团队有哪些

    app开发团队人员构成:作为一个独立的app开发团队,人员架构必须包括产品经理,程序开发人员,测试专员,运营团队,UI 设计.这里是对专业的App开发公司而言,一般个人或团队可能一个人会身兼多职,所以 ...

  3. Solr schema.xml中修改id的类型为int

    使用solr6的版本的时候(solr5不存在这个问题),在修改schema.xml的field时,想使用int做为id的数据类型,修改后重新加载配置的时候报错.原来schema.xml中field i ...

  4. PowerDesigner数据模型(CDM—PDM)

    操作过程 点击:  Tools/Generate Physical Data Model

  5. numpy的通用函数:快速的元素级数组函数

    通用函数(ufunc)是对ndarray中的数据执行元素级运算的函数.可看作简单函数的矢量化包装. 一元ufunc sqrt对数组中的所有元素开平方 exp对数组中的所有元素求指数 In [93]: ...

  6. Python学习进程(11)日期和时间

        本节介绍Python应用程序处理时间和日期的方式.其中转换日期格式是最常用的功能.     (1)获取时间戳: Python 提供了一个 time 和 calendar 模块可以用于格式化日期 ...

  7. MyBatis 插入数据库返回主键

    最近在搞一个电商系统中由于业务需求,需要在插入一条产品信息后返回产品Id,刚开始遇到一些坑,这里做下笔记,以防今后忘记. 类似下面这段代码一样获取插入后的主键 User user = new User ...

  8. 【leetcode刷题笔记】Single Number II

    Given an array of integers, every element appears three times except for one. Find that single one. ...

  9. JS 操作复制剪切粘贴

    测试了很多次之后,虽然有点细碎的突破,但还是想说,麻辣隔壁... 众所周知使用 oncut/oncopy/onpaste 监听剪切板,采用 window.clipboardData 并不是适用于大多浏 ...

  10. 苹果终端wifi图标点亮慢和portal弹窗机制分析以及处理办法和建议

    转:http://kms.h3c.com/View.aspx?id=52875 问题现象 在无线环境中经常碰到苹果终端连接无线后wifi图标无法点亮导致终端无法上网.在起portal的网络中认证页面无 ...