Xstream简介
Xstream是一种OXMapping 技术,是用来处理XML文件序列化的框架,在将JavaBean序列化,或将XML文件反序列化的时候,不需要其它辅助类和映射文件,使得XML序列化不再繁索。Xstream也可以将JavaBean序列化成Json或反序列化,使用非常方便。本文章主要介绍Xstream相关注解的使用。
XStream注解使用
假设要生成如下 xml报文:
<Person>
<_Name attribute="中文名">汤姆</_Name>
<_Sex>Male</_Sex>
<_Age>18</_Age>
<_Address>
<_Country>China</_Country>
<_Province>FuJian</_Province>
<_City>XiaMen</_City>
</_Address>
</Person>
实现流程如下:
1、首先引入相关依赖:
<!--xstream-->
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.9</version>
</dependency>
2、Person.java
/* lombok 注解 */
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@ToString
/* XStream 注解 */
@XStreamAlias("Person")//定义根节点别名
public class Person {
@XStreamOmitField //忽略该属性
private String id;
@XStreamAlias("_Name")//定义属性别名
private XmlElment name;//XmlElment实体主要是为了方便在该标签上添加属性
@XStreamAlias("_Sex")//定义属性别名
private String sex;
@XStreamAlias("_Age")
private int age;
@XStreamAlias("_Address")
private Address address;
}
3、Address.java
/* lombok 注解 */
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class Address {
@XStreamAlias("_Country")
private String country;
@XStreamAlias("_Province")
private String province;
@XStreamAlias("_City")
private String city;
}
4、XmlElment.java
/* lombok 注解 */
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@ToString
/* XStream 注解 */
@XStreamConverter(value= ToAttributedValueConverter.class, strings={"text"})//XStream自带转换器,会将“text”之外的属性定义为节点的属性,text为该节点的值
public class XmlElment{
/* 属性 */
private String attribute;
/* 内容 */
private String text;
}
5、测试方法:
@Test
public void test(){
//定义构造函数使用'XppDriver'防止双下划线问题。
XStream xStream = new XStream(new XppDriver(new XmlFriendlyReplacer("_-", "_")));
xStream.autodetectAnnotations(true);//自动注解扫描,否则注解不生效
// 构造JavaBean
Person p = new Person("1",new XmlElment("中文名", "汤姆"), "Male", 18, new Address("China", "FuJian", "XiaMen"));
System.out.println("实体信息:"+p);
// JavaBean -》 xml
String xml = xStream.toXML(p);
System.out.println("xml内容:");
System.out.println(xml);
// xml -》 JavaBean
Person p2 = (Person) xStream.fromXML(xml);
System.out.println(p2);
}
6、输出结果:
实体信息:Person(id=1, name=XmlElment(attribute=中文名, text=汤姆), sex=Male, age=18, address=Address(country=China, province=FuJian, city=XiaMen))
xml内容:
<Person>
<_Name attribute="中文名">汤姆</_Name>
<_Sex>Male</_Sex>
<_Age>18</_Age>
<_Address>
<_Country>China</_Country>
<_Province>FuJian</_Province>
<_City>XiaMen</_City>
</_Address>
</Person>
Person(id=null, name=XmlElment(attribute=中文名, text=汤姆), sex=Male, age=18, address=Address(country=China, province=FuJian, city=XiaMen))
在遇见XML标签既有既有属性,又有值的情况。如 <_Name attribute="中文名">汤姆</_Name>
。
此处可以使用XmlElment
实体配合@XStreamConverter(value= ToAttributedValueConverter.class, strings={"text"})
注解实现,也可以通过自定义转换器实现。
如下:
XmlElment.java
/* lombok 注解 */
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@ToString
/* XStream 注解 */
@XStreamConverter(ElementConverter.class)//自定义转换器,将text之外的值定义为XML标签属性
public class XmlElment{
/* 属性 */
private String attribute;
/* 内容 */
private String text;
}
ElementConverter.java
public class ElementConverter implements Converter {
@Override
public boolean canConvert(Class type) {
return type.equals(XmlElment.class);
}
/**
* 将java对象转为xml时使用
*/
@Override
public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
XmlElment elment = (XmlElment) source;
writer.addAttribute("attribute", elment.getAttribute());
writer.setValue(elment.getText());
}
/**
* 将xml转为java对象使用
*/
@Override
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
// 在解析order元素时,先创建一个Order对象
XmlElment element = new XmlElment();
// 将attribute元素定义为标签属性
element.setAttribute(reader.getAttribute("attribute"));
// 将text定义为标签值
element.setText(reader.getValue());
return element;
}
}
实现效果和使用自定义转换器是一样的。