作者:黄少存,叩丁狼高级讲师。原创文章,转载请注明出处。
通过之前的四节的学习,相信很多人对 XStream 的基本操作已经掌握的差不多,当然也有一些特殊的操作,比如咱们想自定义 xml 标签的生成方式怎么处理呢?
XStream 允许开发人员自己编写对象和 xml 的转换实现,只需实现 XStream 的 Converter 接口即可
Converter 接口中的方法
- canConvert(clz) : 判断是否是要序列化的类型
- clz : 转换时传入的对象类型
- marshal(value,writer,context) : 将对象转为 XML
- value : 传入需要转 XML 的对象
- writer : 用于书写 xml 的对象
- context : 上下文对象
- unmarshal(reader,context) : 从XML 中解析得到对象
- reader : 用于读取xml数据的对象
- context : 上下文对象
接下咱们就通过 XStream 提供的转换器接口来完成一个需求,
需求:将 User 对象中的 Name 对象的 firstName 和 lastName 作为 xml 中 name 标签的内容并用逗号隔开.
看到这里不知需求能否理解,不过没关系,马上上模型就一目了然了.
模型
@Getter @Setter @ToString @NoArgsConstructor
// XStream 标签
@XStreamAlias("user")
public class User {
private Long id;
private Name name;
public User(String firstName, String lastName) {
this.name = new Name(firstName, lastName);
}
}
@Getter @Setter @ToString @NoArgsConstructor @AllArgsConstructor
class Name {
private String firstName;
private String lastName;
}
OK,有了模型之后咱们就可以来写转换器了,来自定义如何生成 xml 的内容和如何从 xml 中去解析对象.
自定义转换器
public class UserConverter implements Converter {
public boolean canConvert(Class clz) {
return clz.equals(User.class);
}
public void marshal(Object value, HierarchicalStreamWriter writer,
MarshallingContext context) {
User user = (User) value;
writer.startNode("id"); // id 的开始标签
writer.setValue(user.getId().toString()); // id 标签的文本内容
writer.endNode(); // id 的结束标签
writer.startNode("name"); // name 的开始标签
writer.setValue(user.getName().getLastName() + "," // 设置 name 标签的文本内容
+ user.getName().getFirstName()); // name 的结束标签
writer.endNode();
}
public Object unmarshal(HierarchicalStreamReader reader,
UnmarshallingContext context) {
User user = new User();
reader.moveDown(); // 移动 id 开始标签
user.setId(Long.valueOf(reader.getValue())); // 读取标签内容
reader.moveUp(); // 移动 id 标签
reader.moveDown(); // 移动 name 开始标签
String[] name = reader.getValue().split(","); // 读取标签内容
user.setName(new Name(name[1], name[0]));
reader.moveUp(); // 移动 name 结束标签
return user;
}
}
看到这个转换器之后是不是感觉一下就精通了,接下来就来做转换操作.
@Test
public void testConverter() throws Exception {
XStream xStream = new XStream(new StaxDriver());
xStream.autodetectAnnotations(true);
xStream.registerConverter(new UserConverter());
User user = new User("SHAOCUN", "HUANG");
user.setId(2L);
String xml = xStream.toXML(user);
System.out.println(xStream.fromXML(xml));
TransformerUtil.transform(xml, new File("user.xml"));
}
OK 上结果
2
HUANG,SHAOCUN
User(id=2, name=Name(firstName=SHAOCUN, lastName=HUANG))
给力吧,有自己定义的序列化为xml,和反序列化为对象的简答操作就完美终结了.
其实 XStrem 还可以做对象和 JSON 转换,不过本人是觉得用起来比较麻烦,可以用其他的比较专业的 JSON转换 jar 来解决JSON和对象之间的互转.
OK,XStream 的简单使用就到此结束.希望对你有帮助,谢谢!