java xml bean_JAVA Bean和XML之间的相互转换 - XStream简单入门

JAVA Bean和XML之间的相互转换 - XStream简单入门

背景介绍

我们在工作中经常 遇到文件解析为数据或者数据转化为xml文件的情况,之前我一直采用的方式都是手动的来解析或拼接XML文件,这个做法固然是可以的,但是代码部分会显得非常臃肿,所以就查找了相关的资料,发现了一个名为XStream的类库可以做这件事,下面我们来看一下.

XStream的简介

从官网介绍我们能看到以下几个特性:

易用

不需要Mapping文件

不需要额外提供Mapping文件即可完成映射

高性能

高速且低内存消耗

整洁的XML文件

生成的XML的相当简洁

不需要修改对象

可以序列化private修饰的属性,且不需要提供get/set方法

完整的对象结构支持

支持循环引用情况下的输出

兼容其他的XML API

可以对任何的树形结构进行序列化或反序列化

可以自定义的转换策略

可以通过策略的注册,允许自定义特定类型的转化为XML的样式

安全的框架

对未分组的类型进行精细化的控制,防止输入错误而导致的安全问题

良好的异常反馈

当XML文件格式错误的时候,能够提供诊断信息帮助处理

多样的输出格式

不止是XML他还支持JSON及其变种

注解简介

从XStream的官网我们了解到,XStream不需要Mapping文件就能完成JavaBean和XML之间的转变,但大部分时候我们需要对生成的XML文件进行定制,name我们需要了解XStream提供的注解

注解作用适用范围

@XStreamAlias

设置别名

类或属性

@XStreamImplicit

忽略属性

集合类型的属性

@XStreamAsAttribute

将JavaBean转换成节点属性

属性

@XStreamOmitField

忽略属性

属性

@XStreamConverter

注入转换器

应用实例

首先在我们的项目中加入依赖:

com.thoughtworks.xstream

xstream

1.4.11.1

假定环境为Computer和CPU两个类:

public class Computer implements Serializable {

private static final long serialVersionUID = 567119860357020081L;

private String name;

private String brand;

private List processors;

public Computer() {

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getBrand() {

return brand;

}

public void setBrand(String brand) {

this.brand = brand;

}

public List getProcessors() {

return processors;

}

public void setProcessors(List processors) {

this.processors = processors;

}

}

public class CPU implements Serializable {

private static final long serialVersionUID = -718438777162957779L;

private String name;

private String generation;

public CPU() {

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getGeneration() {

return generation;

}

public void setGeneration(String generation) {

this.generation = generation;

}

}

写一个测试方法:

import com.hykj.facheck.entity.CPU;

import com.hykj.facheck.entity.Computer;

import com.thoughtworks.xstream.XStream;

import com.thoughtworks.xstream.io.xml.DomDriver;

import java.util.ArrayList;

import java.util.List;

public class XStreamTest {

public static void main(String[] args) {

List cpuList = new ArrayList<>();

CPU cpu1 = new CPU();

cpu1.setGeneration("8-i5-K");

cpu1.setName("第一个");

cpuList.add(cpu1);

CPU cpu2 = new CPU();

cpu2.setGeneration("8-i5-U");

cpu2.setName("第二个");

cpuList.add(cpu2);

Computer computer = new Computer();

computer.setBrand("huawei");

computer.setName("wej-laptop");

computer.setProcessors(cpuList);

XStream xstream = new XStream(new DomDriver());

xstream.ignoreUnknownElements();

xstream.processAnnotations(Computer.class);

//javabean to xml

String xml = xstream.toXML(computer);

System.out.println(xml);

//xml to javabean

Computer computerFromXml = (Computer) xstream.fromXML(xml);

System.out.println(computer.getName());

}

}

运行程序,控制台打结果如下:

Connected to the target VM, address: '127.0.0.1:53977', transport: 'socket'

wej-laptop

huawei

第一个

8-i5-K

第二个

8-i5-U

Security framework of XStream not initialized, XStream is probably vulnerable.

wej-laptop

Disconnected from the target VM, address: '127.0.0.1:53977', transport: 'socket'

Process finished with exit code 0

45baec7f9a0b18a2feb971ec999f7617.png

也就是说这样就可以用了,很棒棒

但是这个XML和我们的需求不太一样,我们加上注解,代码变成了这样:

import com.thoughtworks.xstream.annotations.XStreamAlias;

import java.io.Serializable;

import java.util.List;

@XStreamAlias("my")

public class Computer implements Serializable {

private static final long serialVersionUID = 567119860357020081L;

private String name;

private String brand;

@XStreamAlias("cpuList")

private List processors;

public Computer() {

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getBrand() {

return brand;

}

public void setBrand(String brand) {

this.brand = brand;

}

public List getProcessors() {

return processors;

}

public void setProcessors(List processors) {

this.processors = processors;

}

}

import com.thoughtworks.xstream.annotations.XStreamAlias;

import java.io.Serializable;

@XStreamAlias("oneCpu")

public class CPU implements Serializable {

private static final long serialVersionUID = -718438777162957779L;

private String name;

private String generation;

public CPU() {

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getGeneration() {

return generation;

}

public void setGeneration(String generation) {

this.generation = generation;

}

}

测试方法不变,结果如下:

Connected to the target VM, address: '127.0.0.1:54181', transport: 'socket'

wej-laptop

huawei

第一个

8-i5-K

第二个

8-i5-U

Security framework of XStream not initialized, XStream is probably vulnerable.

wej-laptop

Disconnected from the target VM, address: '127.0.0.1:54181', transport: 'socket'

Process finished with exit code 0

334d379e63a77e1770689e5fc2d1d485.png

这个XML就很舒服啦.

我们载试一下循环引用的情况吧,代码如下:

import com.thoughtworks.xstream.annotations.XStreamAlias;

import java.io.Serializable;

import java.util.List;

@XStreamAlias("my")

public class Computer implements Serializable {

private static final long serialVersionUID = 567119860357020081L;

private String name;

private String brand;

@XStreamAlias("cpuList")

private List processors;

public Computer() {

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getBrand() {

return brand;

}

public void setBrand(String brand) {

this.brand = brand;

}

public List getProcessors() {

return processors;

}

public void setProcessors(List processors) {

this.processors = processors;

}

}

import com.thoughtworks.xstream.annotations.XStreamAlias;

import java.io.Serializable;

@XStreamAlias("oneCpu")

public class CPU implements Serializable {

private static final long serialVersionUID = -718438777162957779L;

private String name;

private String generation;

private Computer computer;

public CPU() {

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getGeneration() {

return generation;

}

public void setGeneration(String generation) {

this.generation = generation;

}

public Computer getComputer() {

return computer;

}

public void setComputer(Computer computer) {

this.computer = computer;

}

}

import com.thoughtworks.xstream.XStream;

import com.thoughtworks.xstream.io.xml.DomDriver;

import java.util.ArrayList;

import java.util.List;

public class XStreamTest {

public static void main(String[] args) {

Computer computer = new Computer();

computer.setBrand("huawei");

computer.setName("wej-laptop");

List cpuList = new ArrayList<>();

CPU cpu1 = new CPU();

cpu1.setGeneration("8-i5-K");

cpu1.setName("第一个");

cpu1.setComputer(computer);

cpuList.add(cpu1);

CPU cpu2 = new CPU();

cpu2.setGeneration("8-i5-U");

cpu2.setName("第二个");

cpuList.add(cpu2);

cpu1.setComputer(computer);

computer.setProcessors(cpuList);

XStream xstream = new XStream(new DomDriver());

xstream.ignoreUnknownElements();

xstream.processAnnotations(Computer.class);

//javabean to xml

String xml = xstream.toXML(computer);

System.out.println(xml);

//xml to javabean

Computer computerFromXml = (Computer) xstream.fromXML(xml);

System.out.println(computer.getName());

}

}

运行一下,先查看是否构成循环引用:

963418f2eb745f49cd8f18728a08652b.png

确认有循环引用,继续运行代码,控制台打印如下:

Connected to the target VM, address: '127.0.0.1:54221', transport: 'socket'

wej-laptop

huawei

第一个

8-i5-K

第二个

8-i5-U

Security framework of XStream not initialized, XStream is probably vulnerable.

wej-laptop

Disconnected from the target VM, address: '127.0.0.1:54221', transport: 'socket'

Process finished with exit code 0

3c6b2d956e9a3b5bb650813f602881da.png

可以看到生成的XML中采用类似路径的reference属性来标识了位置,实际上我们一般是需要忽略这个属性的,采用@XStreamOmitField注解就好了.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值