概述
XStream不但可以通过编程的方式对XML进行转换,而且支持基于注解的方式。
我们先来看下支持的注解
示例
package com.xgj.oxm.xstream.quickDemo.annotation; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamAsAttribute; import com.thoughtworks.xstream.annotations.XStreamConverter; import com.thoughtworks.xstream.annotations.XStreamImplicit; /** * * * @ClassName: User * * @Description: 使用注解 * * @author: Mr.Yang * * @date: 2017年12月6日 下午9:17:11 */ @XStreamAlias("user") public class User { @XStreamAsAttribute @XStreamAlias("userId") private int id; @XStreamAlias("userName") private String userName; @XStreamAlias("password") private String password; @XStreamAlias("credits") private int credits; @XStreamAlias("lastIp") private String lastIp; @XStreamConverter(DateConverter.class) private Date lastVisit; @XStreamImplicit private List<LoginLog> logs; private Map datas; public List<LoginLog> getLogs() { return logs; } public void setLogs(List logs) { this.logs = logs; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public int getCredits() { return credits; } public void setCredits(int credits) { this.credits = credits; } public String getLastIp() { return lastIp; } public void setLastIp(String lastIp) { this.lastIp = lastIp; } public Date getLastVisit() { return lastVisit; } public void setLastVisit(Date lastVisit) { this.lastVisit = lastVisit; } public void addLoginLog(LoginLog log) { if (this.logs == null) { logs = new ArrayList<LoginLog>(); } logs.add(log); } public Map getDatas() { return datas; } public void setDatas(Map datas) { this.datas = datas; } }
package com.xgj.oxm.xstream.quickDemo.annotation; import java.io.Serializable; import java.util.Date; import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamAsAttribute; import com.thoughtworks.xstream.annotations.XStreamConverter; @XStreamAlias("loginLog") public class LoginLog implements Serializable { private static final long serialVersionUID = 1L; @XStreamAsAttribute @XStreamAlias("id") private int loginLogId; @XStreamAsAttribute private int userId; @XStreamAlias("ip") private String ip; @XStreamAlias("loginDate") @XStreamConverter(DateConverter.class) private Date loginDate; public int getLoginLogId() { return loginLogId; } public void setLoginLogId(int loginLogId) { this.loginLogId = loginLogId; } public int getUserId() { return userId; } public void setUserId(int userId) { this.userId = userId; } public String getIp() { return ip; } public void setIp(String ip) { this.ip = ip; } public Date getLoginDate() { return loginDate; } public void setLoginDate(Date loginDate) { this.loginDate = loginDate; } }
解读
通过 @XStreamAlias为别名注解,一般用于目标类或者字段,比如 @XStreamAlias(“user”) @XStreamAlias(“userId”)
@XstreamConverter注解用于注入自定义的转换器,比如@XStreamConverter(DateConverter.class)注入一个日期转换器
对于集合类型,可以用@XStreamImplicit注解来隐藏,作用和Stream#addImplicitCollection方法一样。
@XStreamAsAttribute注解将Java对象映射为XML元素的一个属性
@XStreamOmitField注解标注的Java对象将不会出现在XML中。
自定义转换器
package com.xgj.oxm.xstream.quickDemo.annotation; import java.text.SimpleDateFormat; import java.util.Date; import com.thoughtworks.xstream.converters.SingleValueConverter; public class DateConverter implements SingleValueConverter { public DateConverter() { } public String toString(Object obj) { try { SimpleDateFormat dateFormat = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss"); dateFormat.setLenient(true); return dateFormat.format(((Date)obj)); } catch (Exception e) { return null; } } public Object fromString(String date) { try { SimpleDateFormat dateFormat = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss"); dateFormat.setLenient(true); return dateFormat.parse(date); } catch (Exception e) { return null; } } public boolean canConvert(Class type) { return type.equals(Date.class); } }
测试类
package com.xgj.oxm.xstream.quickDemo.annotation; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.nio.charset.Charset; import java.util.Date; import com.thoughtworks.xstream.XStream; public class Test { private static XStream xstream; static { xstream = new XStream(); // (1) 第一张方式 手工注册 : 实现该方法,判断要转换的类型 // xstream.processAnnotations(User.class); // xstream.processAnnotations(LoginLog.class); // (2) 第二种方法 自动检测 自动加载注解Bean 推荐 xstream.autodetectAnnotations(true); } // 初始化转换对象 public static User getUser() { LoginLog log1 = new LoginLog(); LoginLog log2 = new LoginLog(); log1.setIp("192.168.1.91"); log1.setLoginDate(new Date()); log2.setIp("127.0.0.1"); log2.setLoginDate(new Date()); User user = new User(); user.setId(1); user.setUserName("xstream"); user.addLoginLog(log1); user.addLoginLog(log2); return user; } /** * JAVA对象转化为XML */ public static void objectToXml() throws Exception { User user = getUser(); FileOutputStream fs = new FileOutputStream( "D://XStreamAnnotationSample.xml"); OutputStreamWriter writer = new OutputStreamWriter(fs, Charset.forName("UTF-8")); xstream.toXML(user, writer); System.out.println("output xml:\n" + xstream.toXML(user)); } /** * XML转化为JAVA对象 */ public static User xmlToObject() throws Exception { FileInputStream fis = new FileInputStream( "D://XStreamAnnotationSample.xml"); InputStreamReader reader = new InputStreamReader(fis, Charset.forName("UTF-8")); User user = (User) xstream.fromXML(fis); for (LoginLog log : user.getLogs()) { if (log != null) { System.out.println("访问IP: " + log.getIp()); System.out.println("访问时间: " + log.getLoginDate()); } } return user; } public static void main(String[] args) throws Exception { objectToXml(); xmlToObject(); } }
解读
要启用XStream提供的注解功能,需要在执行对象和XML转换之前注册标注了XStream注解的Java对象。 比如
xstream.processAnnotations(User.class); xstream.processAnnotations(LoginLog.class);
手工注册User和LoginLog对象。
XStream除了手工注册外,还提供了一个自动检测标注了XStream注解的java对象的方法Xstream#autodetectAnnotations(true),不仅方便,而且提供了缓存机制缓存所有标注了XStream注解的Java对象。
运行结果
output xml: <user userId="1"> <userName>xstream</userName> <credits>0</credits> <loginLog id="0" userId="0"> <ip>192.168.1.91</ip> <loginDate>2017-12-07 21:57:52</loginDate> </loginLog> <loginLog id="0" userId="0"> <ip>127.0.0.1</ip> <loginDate>2017-12-07 21:57:52</loginDate> </loginLog> </user> Security framework of XStream not initialized, XStream is probably vulnerable. 访问IP: 192.168.1.91 访问时间: Thu Dec 07 21:57:52 CST 2017 访问IP: 127.0.0.1 访问时间: Thu Dec 07 21:57:52 CST 2017
示例源码
代码已托管到Github—> https://github.com/yangshangwei/SpringMaster