XStream 1.4.10版本处理xml使用问题
2024-10-21 11:56:32
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
最新文章
- Python任务调度模块 – APScheduler
- 汇编语言写出的helloworld运行过程
- 运行R 报错R cannot R_TempDir, 继而发现/dev/mapper/VG00-LV01 磁盘空间已满
- EXTJS 6 必填项加星号*
- 基于mini2440的boa服务器移植
- 在WINDOWS上安装oracle database 11
- HTML6 展望
- MySQL定时检查是否宕机并邮件通知
- javascript中通过className灵活查找元素 例如我们要把根据class来进行修改样式
- javamail发送邮件的简单实例(转)
- Linux常见命令(三)
- sql替换
- Sass快速入门学习笔记
- Python_查找员工信息-48
- 【C#】读取Excel中嵌套的Json对象,Json带斜杠的问题(其一)
- 微信定时获取token
- logback 实例
- (3.1)mysql基础深入——mysql二进制与源码目录结构介绍
- JSON_CONTAINS
- android 知识小结-1
热门文章
- [Oracle] Io Error: The Network Adapter could not establish the connection 解决方案
- Spring 框架的概述以及Spring中基于XML的IOC配置
- python实战项目 — 使用bs4 爬取猫眼电影热榜(存入本地txt、以及存储数据库列表)
- day46——特殊符号、标签分类、标签
- day37——阻塞、非阻塞、同步、异步
- MySQL数据库-表操作-SQL语句(一)
- crontab 定时删除
- 为了防止页面重新自动加载,可以给a标签设置href=";javascript:void(0);";
- COGS 有标号的DAG/强连通图计数
- Keyboard Purchase CodeForces - 1238E (状压)