一、前言

最近有个需求,需要进行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

package com.ray.scriptenginestudy.xml.parser.util;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.StringReader;
import java.io.StringWriter; /**
*
*/
public class JaxbXmlUtil { /**
* JavaBean转换成xml
* * 默认编码UTF-8
*
* @param obj
* @return
*/
public static String convertToXml(Object obj) {
return convertToXml(obj, "UTF-8");
} /**
* JavaBean转换成xml
* @param obj
* @param encoding
* @return
*/
public static String convertToXml(Object obj, String encoding) {
String result = null;
try {
JAXBContext context = JAXBContext.newInstance(obj.getClass());
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding); StringWriter writer = new StringWriter();
marshaller.marshal(obj, writer);
result = writer.toString();
} catch (Exception e) {
e.printStackTrace();
} return result;
} /**
* xml转换成JavaBean
* @param xml
* @param c
* @return
*/
@SuppressWarnings("unchecked")
public static <T> T converyToJavaBean(String xml, Class<T> c) {
T t = null;
try {
JAXBContext context = JAXBContext.newInstance(c);
Unmarshaller unmarshaller = context.createUnmarshaller();
t = (T) unmarshaller.unmarshal(new StringReader(xml));
} catch (Exception e) {
e.printStackTrace();
} return t;
}
}

3.country.xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<country>
<country_name>中国</country_name>
<provinces>
<province>
<province_name>江苏省</province_name>
<prov_city>南京市</prov_city>
</province>
<province>
<province_name>浙江省</province_name>
<prov_city>杭州市</prov_city>
</province>
</provinces>
</country>

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

4.实体类

(1)Country

package com.ray.scriptenginestudy.xml.parser.demo;

import lombok.Data;

import javax.xml.bind.annotation.*;
import java.util.List; /**
* @author : shira
* @date : 2018/8/2
* @time : 15:15
* @desc :
**/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "country")
@XmlType(propOrder = { "name", "president","provinceList" })
@Data
public class Country { /** 节点 **/
@XmlElement(name = "country_name")
private String name; @XmlElement(name = "president")
private User president; /** 包装节点 **/
@XmlElementWrapper(name = "provinces")
@XmlElement(name = "province")
private List<Province> provinceList; }

(2)User

package com.ray.scriptenginestudy.xml.parser.demo;

import lombok.Data;

import javax.xml.bind.annotation.*;

/**
* @author : shira
* @date : 2018/8/2
* @time : 17:32
* @desc :
**/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(propOrder = { "name" })
@Data
public class User { /** 节点的属性 **/
@XmlAttribute
private String name; /** 节点的文本值 **/
@XmlValue
private String text; }

(3)Province

package com.ray.scriptenginestudy.xml.parser.demo;

import lombok.Data;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType; /**
* @author : shira
* @date : 2018/8/2
* @time : 15:17
* @desc :
**/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(propOrder = { "name", "provCity" })
@Data
public class Province { @XmlElement(name = "province_name")
private String name; @XmlElement(name = "prov_city")
private String provCity;
}

5.测试类

JaxbXmlUtilTest

package com.ray.scriptenginestudy.xml.parser.demo;

import com.ray.scriptenginestudy.xml.parser.util.JaxbXmlUtil;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test; import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List; /**
* @author : shira
* @date : 2018/8/2
* @time : 15:20
* @desc :
**/
@Slf4j
public class JaxbXmlUtilTest { /**
* 1.将实体类转为xml
*/
@Test
public void testBean2Xml() {
//1.创建实体类
Country country = new Country();
country.setName("中国"); User user = new User();
user.setName("习大大");
user.setText("很有优秀的主席");
country.setPresident(user); List<Province> list = new ArrayList<Province>();
Province province = new Province();
province.setName("江苏省");
province.setProvCity("南京市");
Province province2 = new Province();
province2.setName("浙江省");
province2.setProvCity("杭州市");
list.add(province);
list.add(province2); country.setProvinceList(list); //2.将实体类转为xml
String str = JaxbXmlUtil.convertToXml(country);
log.info(str);
} /**
* 2.将xml转为实体类
*/
@Test
public void testXml2Bean() throws IOException {
//1.读取xml
byte[] bytes = Files.readAllBytes(Paths.get("D:\\workspace-study-trial\\script-engine-study\\src\\test\\resources\\demo.xml"));
String xml= new String(bytes);
log.info("xml:{}",xml); //2.将xml转为实体类
Country country = JaxbXmlUtil.converyToJavaBean(xml, Country.class);
log.info("country:{}",country);
}
}

五、JAXB关键类

1.JAXBContext

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

(1)创建 JAXBContext 的实例

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

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

(4)生成Schema文件

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

2.Unmarshaller

将xml转为实体类

3.Marshaller

将实体类转换为xml

六、与脚本引擎结合

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

1.server_script.xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<init-procedure>
<server-script><![CDATA[ function testScript() {
print("1111111");
} testScript(); ]]></server-script> </init-procedure>

2.实体类

InitProcedure

package com.ray.scriptenginestudy.xml.parser.server.script;

import lombok.Data;

import javax.xml.bind.annotation.*;

/**
* @author : shira
* @date : 2018/8/2
* @time : 16:21
* @desc :
**/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "init-procedure")
@XmlType(propOrder = { "serverScript" })
@Data
public class InitProcedure { @XmlElement(name = "server-script")
private ServerScript serverScript; }

ServerScript

package com.ray.scriptenginestudy.xml.parser.server.script;

import lombok.Data;

import javax.xml.bind.annotation.*;

/**
* @author : shira
* @date : 2018/8/2
* @time : 16:33
* @desc :
**/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(propOrder = { "jsimport" })
@Data
public class ServerScript { @XmlAttribute
private String jsimport; @XmlValue
private String cdata; }

3.JAXB工具类

同上

4.测试类

ServerScriptTest

package com.ray.scriptenginestudy;

import com.ray.scriptenginestudy.xml.parser.server.script.InitProcedure;
import com.ray.scriptenginestudy.xml.parser.util.JaxbXmlUtil;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test; import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths; /**
* @author : shira
* @date : 2018/8/2
* @time : 16:23
* @desc :
**/
@Slf4j
public class ServerScriptTest { @Test
public void testServerScript() throws IOException, ScriptException {
//1.解析xml
byte[] bytes = Files.readAllBytes(Paths.get("D:\\workspace-study-trial\\script-engine-study\\src\\test\\resources\\server_script.xml"));
String xml= new String(bytes);
InitProcedure initProcedure = JaxbXmlUtil.converyToJavaBean(xml, InitProcedure.class); //2.准备js脚本
String script=initProcedure.getServerScript().getCdata();
log.info("script:{}",script); //3.创建引擎
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("JavaScript"); //4.执行脚本
engine.eval(script); } }

七、参考资料

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. [转载]分布式session处理方案

    伴随网站业务规模和访问量的逐步发展,原本由单台服务器.单个域名的迷你网站架构已经无法满足发展需要. 此时我们可能会购买更多服务器,并且启用多个二级子域名以频道化的方式,根据业务功能将网站分布部署在独立 ...

  2. OVF and OVA

    最近测试的东西有关于ovf 和ova等相关用例,在网上找了点内容摘抄了下来. 一.什么是OVF文件 开源虚拟化格式OVF文件是一种开源的文件规范,它描述了一个开源.安全.有效.可拓展的便携式虚拟打包以 ...

  3. 2015/7/29 (高开,V形反转,各种指标背离——可惜没买进,填补空缺图形的心理分析)

    1.李大--謝先生℡:早盘决策:如今日再次出现大幅低开  或者盘中大幅下跌可逢低 3成仓位左右分散资金做短线抄底,切记是超短 绝不追高,设置5个点止损.市场有很多名家在谈论3373点即前低点,本人告诉 ...

  4. 纯HTML标签详解(摘自阿里西西)

    HTML标签很多,可是实际上常用的却就那么十几二十个,很多标签的功能渐渐的被大家忽略了.然后,如果在适当的时候,用一用,还是能在一定程序上给我们的页面设计带来一点小小的方便的.下面这些HTML标签基本 ...

  5. 每天一个Linux命令(51)ss命令

        ss命令用来显示处于活动状态的套接字信息.     (1)用法:     用法:  ss  [参数]  ss  [参数]  [过滤]     (2)功能:     功能:  ss是类似nets ...

  6. MySQL修改管理员账户密码

    报错提示:ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)MySQL代理报错提示: ...

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

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

  8. P4299 首都

    题目 P4299 首都 做法 这题是动态维护树的重心,连边后找到两棵树的重心拉一条链(性质:新重心在链上),然后暴力爬 要注意: 1.是找重心的过程中要先把旋转标记放下来,因为\(Splay(x)\) ...

  9. PHP字符串函数大全

    无论哪种编程语言,字符串操作都是一个重要的基础,往往简单而重要.PHP为我们提供了大量的字符串操作函数,功能强大,使用也比较简单.在这里结合实例总结分析PHP字符串函数的功能. 1.addcslash ...

  10. hive -e 时转义需要再加一个\

    hive窗口中使用转义字符: select split(concat_ws('|','123','456','789'),'\\|')from dual; 参考 http://jingyan.baid ...