java xstream jar_xStream.jar踩坑指南

本文介绍了在使用XStream进行XML字符串到对象转换时遇到的问题及解决过程,包括安全框架未初始化、类转换错误等。通过设置别名、允许类型、初始化安全框架等方式解决了问题,并探讨了XStream的使用方法和注意事项,如XML和Json的序列化、反序列化,以及注解的使用和自定义转换器。
摘要由CSDN通过智能技术生成

前言

第一次接触Xstream,是在做一个socket通信的项目,由于是二次重新开发,所以有部分代码沿用了原来的代码(改造前用的webservice),其中xml字符串转换为对象,以及对象转换为xml字符串的代码用到了这个包,所以我也就照葫芦画瓢,最终把项目顺利做完了,由于没有遇到什么问题,所以也就没有对Xstream做深入的了解和探索,直到前几天又接手到一个新的项目,里面接口调用涉及到同样的业务需求,然后就再次想到Xstream,然后很自然地遇到了一些问题,所以也就有了这篇文章,好了,废话少说,直接开始吧。

过程:我太难了|

由于上次用过,所以我就自以为轻车熟路的开始了,下面是收到的消息体(也就是需要转换成对象的xml字符串):

认证成功

张三

610123456789012345

1

然后我就按照自己的理解,创建了消息体对象:

// 为了方便,我省略了get/set方法,一下同

// 文件名: MsgText.java

public class MsgText {

private Result result;// 结果

}

// 文件名: Result.java

public class Result {

private String message;// 消息

private Data data; // 数据

private String code; // 消息代码

}

// 文件名: Data.java

public class Data {

private String AAC003;

private String AAC002;

}

下面是业务代码,也是以及我的理解写:

String result = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>认证成功张三6101234567890123451";

XStream xstream = new XStream(new StaxDriver());

xstream.alias("MsgText", MsgText.class);

MsgText fromXML = (MsgText)xstream.fromXML(result);

毫无疑问地报错,以下是报错信息:

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

Exception in thread "main" com.thoughtworks.xstream.mapper.CannotResolveClassException: result

经过查找资料,第一行错误是初始化失败,查到的资料如下:

意思是:xstream 的安全框架没有初始化,xstream 容易受攻击。

解决方法:xStream对象设置默认安全防护,同时设置允许的类

解决代码如下:

XStream.setupDefaultSecurity(xStream); // 其中xStream是你实例的XStream的变量名,这是个静态方法

xStream.allowTypes(new Class[]{Test.class, Test1.class});

设置完成后,第二行依然报错,查了很多资料,问题依然没有解决,然后我打算按照自己的理解先做一些尝试,然后在设置别名那里增加了一行代码:

xstream.alias("Result", Result.class);

错误依旧,然后我又加入了一行代码:

xstream.alias("Data", Data.class);

可依然还是相同的错误,我都快疯了,但问题总是要解决吧,可能是运气好,我都不知道自己怎么想到的,觉得可能是alias方法的大小写有问题,然后就经过N次的尝试和摸索,终于报错变了,变成类转换异常:

代码如下:

XStream xstream = new XStream(new StaxDriver());

xstream.alias("msgtext", MsgText.class);

xstream.alias("result", Result.class);

xstream.alias("data", Data.class);

Class>[] classes = new Class[] { MsgText.class, Result.class,Data.class };

XStream.setupDefaultSecurity(xstream);

xstream.allowTypes(classes);

MsgText fromXML = (MsgText)xstream.fromXML(result);

错误如下:

Exception in thread "main" java.lang.ClassCastException: lss.test.reckoner.util.Result cannot be cast to lss.test.reckoner.ejb.MsgText

at lss.test.reckoner.ejb.Test.main(Test.java:20)

然后,这时候我才恍然大悟,原来报文根对象必须是根节点(result),接着我把最后一行代码改成如下:

Result fromXML = (Result)xstream.fromXML(result);

然后就再也不报错了,接着我觉得那应该和msgtext和data都没有关系,然后删除了下面的代码:

xstream.alias("msgtext", MsgText.class);

xstream.alias("data", Data.class);

也把这里:

Class>[] classes = new Class[] { MsgText.class, Result.class,Data.class };

改成:

Class>[] classes = new Class[] { Result.class};

到此问题已经完美解决了

总结

xml对象对应的是xml字符串的根节点,本例中就是Result,而不是我理解的MsgText

xstream.alias("msgtext", MsgText.class)这个方法设置别名对应是xml的节点名,大小写要一致

拓展

这里再拓展些xstream的知识点

关于XStream

XStream是一个简单的库,用于将对象序列化为XML并再次返回。

特征

使用方便。提供高级外观,简化了常见用例。

不需要映射。大多数对象都可以序列化,而无需指定映射。

性能。速度和低内存占用是设计的关键部分,使其适用于具有高消息吞吐量的大型对象图或系统。

清洁XML。没有重复的信息可以通过反射获得。这导致XML更容易为人类阅读,并且比本机Java序列化更紧凑。

不需要修改对象。序列化内部字段,包括私有和最终字段。支持非公开和内部类。类不需要具有默认构造函数。

完整对象图支持。将维护在对象模型中遇到的重复引用。支持循环引用。

与其他XML API集成。通过实现接口,XStream可以直接与任何树结构(而不仅仅是XML)进行串行化。

可定制的转换策略。可以注册策略,允许自定义特定类型如何表示为XML。

安全框架。对未编组类型进行精细控制,以防止受操纵输入的安全问题。

错误消息。当由于格式错误的XML而发生异常时,会提供详细的诊断信息以帮助隔离和修复问题。

替代输出格式。模块化设计允许其他输出格式。XStream目前提供JSON支持和变形。

使用

创建XStream 对象

有两种创建方式:

第一种:不需要XPP3库 开始使用Java6

XStream xstream = new XStream(new StaxDriver());

第二种:需要XPP3库

XStream xstream = new XStream();//需要XPP3库

注意: Xstream序列化XML时需要引用的jar包:xstream-[version].jar、xpp3-[version].jar、xmlpull-[version].jar。Xstream序列化Json需要引用的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值