首页 > 其他分享 >JAXB 使用记录

JAXB 使用记录

时间:2022-09-18 21:45:03浏览次数:102  
标签:xml String 记录 JAXB javax 使用 import public name

JAXB 使用记录

目录

参考资料

什么是 JAXB ?

开源中国:

JAXB(Java Architecture for XML Binding简称JAXB)允许Java开发人员将Java类映射为XML表示方式。JAXB提供两种主要特性:将一个Java对象序列化为XML,以及反向操作,将XML解析成Java对象。换句话说,JAXB允许以XML格式存储和读取数据,而不需要程序的类结构实现特定的读取XML和保存XML的代码。

使用

1.基本使用

1.1 编写User类

package org.black.demo.xstream;

import java.io.Serializable;
import java.util.Arrays;

import javax.xml.bind.annotation.XmlRootElement;

/**
 * 用户
 */
@XmlRootElement
//@XmlElement
public class User implements Serializable
{
    // serialVersionUID IDE自动生成的序列化ID
	private static final long serialVersionUID = -3552351542858137630L;
	// 姓名
	private String name;
	// 性别
	private String sex;
	// 年龄
	private Integer age;
	// 身高
	private Double height;
	// 分数
	private Double[] points;
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	public Double getHeight() {
		return height;
	}
	public void setHeight(Double height) {
		this.height = height;
	}
	
	public Double[] getPoints() {
		return points;
	}
	public void setPoints(Double[] points) {
		this.points = points;
	}
	@Override
	public String toString() {
		return "User [name=" + name + ", sex=" + sex + ", age=" + age + ", height=" + height + ", points=" + Arrays.toString(points) +"]";
	}
}

1.2 编写测试类

package org.black.demo.jaxb;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.StringWriter;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

import org.black.demo.xstream.User;

import com.sun.xml.internal.messaging.saaj.util.ByteInputStream;
import com.sun.xml.internal.messaging.saaj.util.ByteOutputStream;

public class JavaArcXMlBean {

	public static void main(String[] args) {

		try {
			// contextPath 是Java对象的包名集合,test.jaxb就是包名
			JAXBContext jc = JAXBContext.newInstance(User.class);
			// marshalling 是计算机科学中把一个对象的内存表示变换为适合存储或发送的数据格式的过程
			// marshaller 是控制 marshalling 处理
			Marshaller marshaller = jc.createMarshaller();
			User admin = new User();
			admin.setName("管理员111");
			admin.setAge(27);
			admin.setHeight(180.00);
			admin.setSex("男");
			Double[] points = new Double[2];
			points[0] = 182.00;
			points[1] = 100.00;

			admin.setPoints(points);
			marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, new Boolean(true));
			// 将Java对象序列化为xml 文件
			ByteOutputStream bo = new ByteOutputStream();
			marshaller.marshal(admin, bo);
			bo.flush();
			bo.close();
			ByteInputStream bi =  bo.newInputStream();
			System.out.println("序列化后:" + new  String (bi.getBytes())); 
			Unmarshaller unmarshaller = jc.createUnmarshaller();
			// 真正反序列化 xml 文件,得到
			User adminCpoy = (User) unmarshaller.unmarshal(bi);
			bi.close();
			System.out.println("adminCpoy:" + adminCpoy);

		} catch (JAXBException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

}

1.3 验证

序列化后:<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<user>
    <age>27</age>
    <height>180.0</height>
    <name>管理员111</name>
    <points>182.0</points>
    <points>100.0</points>
    <sex>男</sex>
</user>

adminCpoy:User [name=管理员111, sex=男, age=27, height=180.0, points=[182.0, 100.0]]

2 改进版

单独写一个JAXBUtil.Java工具类 提供序列化和反序列化方法.

2.1 JAXBUtil 工具类

package org.black.demo.jaxb;

import java.io.IOException;
import java.io.StringReader;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.Source;
import javax.xml.transform.sax.SAXSource;

import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;

import com.sun.xml.internal.messaging.saaj.util.ByteOutputStream;

/**
 * JAXB 序列化工具类
 * @author black
 * @date 2021-12-10 18:44:038
 */
public class JAXBUtil {
	
	/**
	 * 序列化为xml字符串
	 * @param obj
	 * @return
	 * @throws JAXBException
	 * @throws IOException 
	 */
	
	public static String serialize(Object obj) throws JAXBException, IOException {
		// contextPath 是Java对象的包名集合,test.jaxb就是包名
		JAXBContext jc;
		StringBuilder builder = new StringBuilder();
		try (ByteOutputStream bo = new ByteOutputStream();) {
			jc = JAXBContext.newInstance(obj.getClass());
			// marshalling 是计算机科学中把一个对象的内存表示变换为适合存储或发送的数据格式的过程
			// marshaller 是控制 marshalling 处理
			Marshaller marshaller = jc.createMarshaller();
			marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, new Boolean(true));
			// 将Java对象序列化为xml 字符串
			marshaller.marshal(obj, bo);
			bo.flush();
			return new String(bo.getBytes(),"utf8");
		}
	}
	
	/**
	 * xml字符串反序列化为对象
	 * @param <T> 
	 * @param in
	 * @param t
	 * @throws JAXBException
	 * @throws ParserConfigurationException 
	 * @throws SAXException 
	 */
	public static <T> T deserialize(String xml, T t) throws JAXBException, SAXException, ParserConfigurationException {
		JAXBContext jc = JAXBContext.newInstance(t.getClass());
		Unmarshaller unmarshaller = jc.createUnmarshaller();
		Source source =  trunSource(xml);
		JAXBElement<? extends Object> et = unmarshaller.unmarshal(source,t.getClass());
		 return (T)et.getValue();
	}
	
	
	private static Source trunSource(String xmlStr) throws SAXException, ParserConfigurationException{
		 StringReader reader = new StringReader(xmlStr); 
	     SAXParserFactory sax = SAXParserFactory.newInstance();  
        sax.setNamespaceAware(false);  
        XMLReader xmlReader = sax.newSAXParser().getXMLReader();
        Source source = new SAXSource(xmlReader, new InputSource(reader));  
		 return source;		
	}
}

2.2 编写 XML 对应类

xml 节点结构:

<root>
    +
	+ ---- <header>
	+
	+ ---- <object>
	+ ---- <object>
    ...
</root>
2.2.1 root 节点
package org.black.demo.jaxb;

import java.util.List;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementRef;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "root")
public class XMLFileRoot {

	// root 标签属性 id
	@XmlAttribute
	private String id;

	// root 标签属性 type
	@XmlAttribute
	private String type;

	// root 标签子标签 header
	@XmlElement(name = "header")
	private XMLHeader header;

	// XmlElementRef 根据 ContentObject 类型来映射xml 标签
	@XmlElementRef
	private List<ContentObject> objects;
	
	// 无参构造器必须存在,否则报"does not have a no-arg default constructor"
	public XMLFileRoot() {
	}
	
	public XMLFileRoot(String id, String type) {
		super();
		this.id = id;
		this.type = type;
	}

	public void setHeader(XMLHeader header) {
		this.header = header;
	}

	public void setObjects(List<ContentObject> objects) {
		this.objects = objects;
	}
}

2.2.2 header 节点
package org.black.demo.jaxb;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlValue;

@XmlRootElement(name = "header")
public class XMLHeader {

	// header 标签属性 name
	@XmlAttribute
	private String name;

	// header 标签属性 desc
	@XmlAttribute
	private String desc;
	
	// header 标签的值,示例: <header>"<![CDATA[ p=abc ]]></header>
	@XmlValue
	private String metadate ="<![CDATA[+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs]]>";

	public void setName(String name) {
		this.name = name;
	}

	public void setDesc(String desc) {
		this.desc = desc;
	}
}
2.2.3 object 节点(多个)

object 存在公用属性 id 和 desc,这里我提取了一个父类 ContentObject,并用 @XmlSeeAlso 指定 子类使用ContentObject的属性:

package org.black.demo.jaxb;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlSeeAlso;

// @XmlSeeAlso 指示 JAXB 绑定这个类时,也绑定其他类
@XmlSeeAlso(value = {Book.class, Phone.class})
public class ContentObject {
	@XmlAttribute
	protected String id;
	
	@XmlAttribute
	protected String name;
	
}

两个子类 Book 和Phone:

package org.black.demo.jaxb;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="object")
public class Book extends ContentObject{

	// 价格
	@XmlAttribute
	private Double price;
	
	// 无参构造器必须存在,否则报"does not have a no-arg default constructor"
	public Book() {
		
	}
	
	 public Book(String id, String name) {
		this.id = id;
		this.name = name;
	}

	public void setPrice(Double price) {
		this.price = price;
	}
}

package org.black.demo.jaxb;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "object")
public class Phone extends ContentObject {

	// 生产日期
	@XmlAttribute
	private String createDate;

	// 无参构造器必须存在,否则报"does not have a no-arg default constructor"
	public Phone() {

	}

	public Phone(String id, String name) {
		this.id = id;
		this.name = name;
	}

	public void setCreateDate(String createDate) {
		this.createDate = createDate;
	}
}

2.3 编写测试类并进行测试

package org.black.demo.jaxb;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.xml.bind.JAXBException;

public class JaxbUtilTest {

	public static void main(String[] args) {
		// root
		XMLFileRoot root = new XMLFileRoot("1", "root");

		// header
		XMLHeader header = new XMLHeader();
		header.setName("xml head");
		header.setDesc("这是Jaxb 生成的xml格式数据");

		root.setHeader(header);

		// object
		List<ContentObject> objects = new ArrayList<ContentObject>();
		Book book = new Book("1", "诛仙");
		// 价格
		book.setPrice(88.00);
		Phone phone = new Phone("2", "苹果手机");
		// 生产日期
		phone.setCreateDate("2022-01-01 00:00:00");
		objects.add(book);
		objects.add(phone);

		root.setObjects(objects);

		// 生成xml
		String xml;
		try {
			xml = JAXBUtil.serialize(root);
			System.out.println("生成的XML :");
			System.out.println(xml);
		} catch (JAXBException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

测试结果:

生成的XML :
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root id="1" type="root">
    <header name="xml head" desc="这是Jaxb 生成的xml格式数据">&lt;![CDATA[+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs]]&gt;</header>
    <object price="88.0" id="1" name="诛仙"/>
    <object createDate="2022-01-01 00:00:00" id="2" name="苹果手机"/>
</root>

标签:xml,String,记录,JAXB,javax,使用,import,public,name
From: https://www.cnblogs.com/lihw-study/p/15673260.html

相关文章

  • git使用
    gitee使用9个步骤:1.创建项目,初始化项目,并设置项目账号 ①创建项目D:\workspace\java01\giteedemo ②初始化本地库gitinit(在项目当前目录下,执行命令) 生成.git文......
  • Mac使用经验汇总
    在此记录使用Mac的一些经验技巧。安装brew如果按照官网提示安装,巨慢无比,如下:/bin/bash-c"$(curl-fsSLhttps://raw.githubusercontent.com/Homebrew/install/HEAD/......
  • 使用ssh连接virtual Box里的虚拟机
    使用ssh连接virtualBox里的虚拟机需求:virtualBox提供的文件拖放功能在从虚拟机拖向主机时,会出现一些卡顿,因此考虑使用ssh代替其文件传输功能。高级->端口转发......
  • Ubuntu 20.04 使用 socat 转发特定端口
    安装socataptinstallsocat根据需求确定要转发的端口比如,我的需求是监听IPv6的某一TCP端口,并转发至局域网内某一特定主机,可以使用以下命令:socatTCP6-LISTEN:xxxx,fo......
  • 【博学谷学习记录】超强总结,用心分享 。SpringBoot 常用注解
    @RequestMapping@RequestMapping注解的主要用途是将Web请求与请求处理类中的方法进行映射。SpringMVC和SpringWebFlux都通过RquestMappingHandlerMapping和RequestMappi......
  • Qt之QLabel文本内容太长时可以使用省略号
    在使用QLabel进行文本内容显示时,有时候可能文本长度过长,会导致文本显示不全的问题,这个时候可以将文本内容的剩余部分使用...显示代码如下:MainWindow::MainWindow(QWidge......
  • 轻松使用 Debian的Linux
    Spiral Linux 就是这样一种发行版,它源于Debian。它的重点在于促进简单性并为最终用户提供开箱即用的特性和功能。如果您是开源操作系统的新手,并且想熟悉一个易于使用......
  • 使用 C# 承载 Flutter Desktop 进行插件开发
    FlutterSharpGoogle官方迟迟没有支持使用C#进行FlutterDesktop的插件开发,本Demo初步跑通,原创不易,如果对您有所帮助,请赐一个✨哈哈,详见https://github.com/Live......
  • SQLZOO记录 2:窗口函数
    SQL窗口函数包括LAG、LEAD、RANK和NTILE。这些函数在行的“窗口”上运行——通常是表中某种意义上相邻的行。9-WindowfunctionsShowthelastName,partyandv......
  • css简单动画 @-webkit-keyframes、-webkit-transform、webkit-animation的使用
    浏览器前缀IE10和Firefox(>=16)支持没有前缀的animation,firefox(<16)使用-moz-前缀,因为现在firefox的版本也都不低,所以firefox都直接使用没有前缀的animation。而chrome,safa......