XStream pom依赖:

<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.10</version>
</dependency>

1、对象解析成xml字符串时下划线变成双下划线

解决:

xStream = new XStream(new DomDriver("UTF-8", new XmlFriendlyNameCoder("_-", "_")));

或者

xStream = new XStream(new Xpp3Driver(new NoNameCoder()));

2、Security framework of XStream not initialized, XStream is probably vulnerable

解决:

XStream.setupDefaultSecurity(xStream);
xStream.allowTypesByWildcard(new String[] {
"com.common.util.**" //你的包路径
});

3、处理既有属性又有值的情况

形如:<Query Code="1">select * from user</Query>

使用自定义转换器实现,如下:

public class QueryConverter implements Converter {
@Override
public boolean canConvert(Class type) {
return type.equals(Query.class);
} /**
* 将java对象转为xml时使用
*/
@Override
public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
Query query = (Query) source;
// 设置属性值
writer.addAttribute("Code", query.getCode());
// 设置文本值
writer.setValue(query.getText());
} /**
* 将xml转为java对象使用
*/
@Override
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
Query query = new Query();
query.setTransactionCode(reader.getAttribute("Code"));
query.setText(reader.getValue());
return query;
}
}

之后通过注解@XStreamConverter(value = QueryConverter.class)

或代码注册转换器使用:

xStream.registerConverter(new xxxConverter());

4、时间转换器

字段为Date类型

public class DateConverter implements Converter {

    @Override
public boolean canConvert(Class arg0) {
return Date.class == arg0;
} @Override
public void marshal(Object arg0, HierarchicalStreamWriter arg1, MarshallingContext arg2) {
} @Override
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext arg1) { GregorianCalendar calendar = new GregorianCalendar();
//格式化当前系统日期
SimpleDateFormat dateFm = new SimpleDateFormat("yyyy-MM-dd");
try {
calendar.setTime(dateFm.parse(reader.getValue()));
} catch (ParseException e) {
throw new ConversionException(e.getMessage(), e);
} return calendar.getTime();
}
}

使用:

@XStreamConverter(DateConverter.class)
private Date beginTime;

属性为Date类型处理SingleValueConverter

public class XStreamDateConverter implements SingleValueConverter {

    @Override
public boolean canConvert(Class arg0) {
return Date.class == arg0;
} @Override
public Object fromString(String arg0) {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
try {
return format.parse(arg0);
} catch (ParseException e) {
e.printStackTrace();
}
return null;
} @Override
public String toString(Object arg0) {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
try {
return format.format((Date) arg0);
} catch (Exception e) {
e.printStackTrace();
}
return "";
} }

之后将转化加在Date属性的字段上使用即可

@XStreamConverter(value=XStreamDateConverter.class)
@XStreamAsAttribute
private Date beginTime;

5、针对null值的字段也显示在xml中处理

大概思路就是遍历对象的所有的字段,若当前字段的值为null,则处理成空字符串,示例自定义转换器如下:

public class FieldConverter implements Converter {

    /**
* 日志记录
*/
private static final Logger LOGGER = LoggerFactory.getLogger(FieldConverter.class); /**
* 时间格式
*/
private String formatPattern; public FieldConverter() {
} public FieldConverter(String formatPattern) {
this.formatPattern = formatPattern;
} @Override
public boolean canConvert(Class type) {
return true;
} /**
* 将java对象转为xml时使用
*/
@Override
public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
try {
handleSource(source, writer);
} catch (Exception e) {
LOGGER.error("[FieldConverter] marshal 异常,{}", e);
throw new IllegalArgumentException("转换xml出错");
}
} /**
* @description :处理对象为xml转换
* @param source 对象源
* @param writer 流写出对象
* @date 2019/9/29 18:48
* @modifier
* @return void
*/
private void handleSource(Object source, HierarchicalStreamWriter writer) throws IllegalAccessException { try {
Class<?> aClass = source.getClass();
Field[] declaredFields = aClass.getDeclaredFields();
for (Field currField : declaredFields) {
currField.setAccessible(Boolean.TRUE);
// 字段注解
boolean isAttr = currField.isAnnotationPresent(XStreamAsAttribute.class);
boolean isXStreamAlias = currField.isAnnotationPresent(XStreamAlias.class);
boolean isFieldValue = currField.isAnnotationPresent(FieldValue.class); // 当前字段值
Object curFieldValue = currField.get(source); // 字段别名
String xmlAlias;
if (isXStreamAlias) {
xmlAlias = currField.getAnnotation(XStreamAlias.class).value();
} else {
xmlAlias = currField.getName();
} if (isAttr) {
// 字段属性
writer.addAttribute(xmlAlias, null == curFieldValue ? "" : String.valueOf(curFieldValue));
} else if (isFieldValue) {
// 字段值
writer.setValue(String.valueOf(curFieldValue));
} else {
// 字段简单处理
boolean isBaseType = DomainUtil.isBaseType(currField.getType());
if (curFieldValue instanceof List) {
List<Object> list = (List<Object>) curFieldValue;
for (int i = 0; i < list.size(); i++) {
writer.startNode(xmlAlias + i);
Object curr = list.get(i);
isBaseType = DomainUtil.isBaseType(curr.getClass());
if (null == curr || isBaseType) {
writer.setValue(null == curr ? "" : String.valueOf(curr));
} else {
handleSource(curr, writer);
}
writer.endNode();
}
} else {
// 开始节点
writer.startNode(xmlAlias); if (null == curFieldValue || isBaseType) {
writer.setValue(null == curFieldValue ? "" : String.valueOf(curFieldValue));
} else if (currField.getType().equals(Date.class)) { //时间对象
SimpleDateFormat format = new SimpleDateFormat(formatPattern);
writer.setValue(null == curFieldValue ? "" : format.format(curFieldValue));
} else { //对象类型
handleSource(curFieldValue, writer);
} // 结束节点
writer.endNode();
}
}
}
} catch (Exception e) {
LOGGER.error("[FieldConverter] handleSource 异常,{}", e);
throw e;
}
} /**
* 将xml转为java对象使用
*/
@Override
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
System.out.println("coming.....");
return null;
}

源码参照 GitHub

XStream 1.4.10版本处理xml使用问题的更多相关文章

  1. 升级 python 2.6.6 系统到 2.7.10 版本

    CentOS 6 系统默认 Python 版本是:2.6.6 平时在使用中遇到很多的库要求是 2.7.x 版本的库,比如使用 ConfigParser 库,在 2.6 版本库就不支持没有 value ...

  2. Windows 10 版本 1507 中的新 AppLocker 功能

    要查看 Windows 10 版本信息,使用[运行]> dxdiag  回车 下表包含 Windows 10 的初始版本(版本 1507)中包括的一些新的和更新的功能以及对版本 1511 的 W ...

  3. 20160303 - 升级 Windows 10 版本 1511 后,文件夹默认打开方式为 cmd 的修复

    问题描述:升级 Windows 10 版本 1511 (OS 内部版本 10586.122)后,文件夹的默认打开方式变成了cmd.双击任何一个文件夹,显示相关的提示错误信息如下: [Window Ti ...

  4. 设置Ubuntu 10.10版本的软件源

    设置Ubuntu 10.10版本的软件源 http://blog.csdn.net/xie1xiao1jun/article/details/49911189   网上有很多关于软件源信息的更新,每次 ...

  5. VS2013+Win10+opencv3.0配置(包括opencv2.4.10版本)

    在win下配置opencv3.0.0还是比较简单的,这里简单说一下配置过程:参考链接:http://blog.csdn.net/u010009145/article/details/50756751 ...

  6. swoole1.8.0+版本异步redis安装(本实例为swoole1.8.10版本)详解

    Swoole-1.8.0+版本增加了对异步Redis客户端的支持,基于redis官方提供的hiredis库实现.Swoole提供了__call魔术方法,来映射绝大部分Redis指令(本次安装实例为sw ...

  7. websocket通讯协议(10版本)简介

    前言: 工作中用到了websocket 协议10版本的,英文的协议请看这里: http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotoc ...

  8. Windows 10 版本信息

    原文 https://technet.microsoft.com/zh-cn/windows/release-info Windows 10 版本信息 Microsoft 已更新其服务模型. 半年频道 ...

  9. 从Ubuntu 18.04 LTS升级到Ubuntu 18.10版本的方法

    从Ubuntu 18.04 LTS升级到Ubuntu 18.10版本的方法 2018-10-18 21:08:39作者:ywnz稿源:云网牛站 本文提供从Ubuntu 18.04 LTS(Bionic ...

随机推荐

  1. 1.JVM前奏篇(看官网怎么说)

    JVM(Java Virtual Machine) 前奏篇(看官网规范怎么说) 1.The relation of JDK/JRE/JVM 在下图中,我们所接触的,最熟悉,也是经常打交道的 最顶层 J ...

  2. SpringBoot(1)

    SpringBoot 8/2 CRUD 发送put请求修改数据有三个步骤: SpringMVC中配置HiddenHttpMethodFilter 页面上创建一个post请求(form标签只能写get和 ...

  3. new/delete与命名空间

    目录 1. new/delete 2. 命名空间 1. new/delete C++中的动态内存分配 C++通过new关键字进行动态内存申请 C++中的动态内存申请是基于类型进行的 delete关键字 ...

  4. 小贴士--Python

    1.查看python安装好的包版本信息:pip list 原贴,有空完善.http://yangzb.iteye.com/blog/1824761 2.Python文件快速执行. 加头文件快速执行Py ...

  5. wpf Log4net的配置和使用

    现在项目涉及的是cs客户端,在项目中使用log4net记录本地日志和异常信息,这里项目做完了,想着自己做一个demo,测试记录一下log4Net的配置使用. 第一步.新建一个wpf应用程序,项目右键 ...

  6. PLSQL登录失败出现空白错误提示框的问题

    安装win7后其他软件运行正常,可是数据库用cmd plsplus和plsql软件都连不上,plsql报一个空白提示框 重装n遍oracle客户端,都不行. 最后发现解决方式很简单,在plsql的图标 ...

  7. ③ Python3.0 数字类型

    Python3 的六个标准数据类型中:不可变数据(3 个):Number(数字).String(字符串).Tuple(元组):可变数据(3 个):List(列表).Dictionary(字典).Set ...

  8. C语言中特殊字符含义

    字符 中文 英文 说明  \n  换行符  newline     \t      Tab键  \b    backspace  退格键                        

  9. windows下cuda的安装

    1. cuda的安装 到 https://developer.nvidia.com/cuda-toolkit 去下载.在安装的时候一定要自定义安装,否则将会安装很多无用的东西.安装的选项,可以选择不更 ...

  10. HTML Marquee跑马灯

    Marquee是html的标签,所有的主流浏览器都能兼容,用于创建文字滚动. 来介绍下标签的属性 滚动方向 direction <!--滚动方向 direction 4个值 up down le ...