Java_数据交换_JAXB_用法入门
Posted shirui
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java_数据交换_JAXB_用法入门相关的知识,希望对你有一定的参考价值。
一、前言
最近有个需求,需要进行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应用实例
以上是关于Java_数据交换_JAXB_用法入门的主要内容,如果未能解决你的问题,请参考以下文章
将Java从1.8.0_45更新为1.8.0_131后,JAXB unmarshal字段为空
C#面试题0_编码题_下列代码输出的是什么_Java instanceof用法
关于__IPHONE_OS_VERSION_MAX_ALLOWED和__IPHONE_OS_VERSION_MIN_ALLOWED的用法