大家好,又见面了,我是你们的朋友全栈君。
XStream是一套简洁易用的开源类库,用于将Java对象序列化为XML或者将XML反序列化为Java对象,是Java对象和XML之间一个双向转换器。
1.XStream概述
2.快速入门
User.java:
代码语言:javascript复制public class User implements Serializable {
private static final long serialVersionUID = 1L;
private int userId;
private String name;
public User() {}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
代码语言:javascript复制public class XStreamSample_01 {
private static XStream xstream;
static {
//创建一个XStream实例并指定一个XML解析器
xstream = new XStream(new DomDriver());
}
//初始化转换对象
public static User getUser() {
User user = new User();
user.setUserId(1);
user.setName("XStreamSample");
return user;
}
//Java对象转化为XML
public static void objectToXML() throws Exception {
//1.获得要转化的Java对象实例
User user = XStreamSample_01.getUser();
//2.实例化一个文件输出流
FileOutputStream outputStream = new FileOutputStream("D:\temporary\XStream\user.xml");
//3.将User对象转换为XML,并保存到指定文件
xstream.toXML(user, outputStream);
}
//XML转化为Java对象
public static void XMLToObject() throws Exception {
//实例化一个文件输入流
FileInputStream inputStream = new FileInputStream("D:\temporary\XStream\user.xml");
//将XML文件输入流
User user = (User)xstream.fromXML(inputStream);
System.out.println("user's id: " user.getUserId());
System.out.println("user's name: " user.getName());
}
}
3.使用XStream别名:
XStream别名配置包含三种情况:
①.类别名,用alias(String name, Class type)
②.类成员别名,用aliasField(String alias, Class definedIn, String fieldName)
③.类成员作为属性别名,用aliasAttribute(String alias, String attributeName, String alias)单独命名没有意义,还要通过useAttributeFor(Class definedIn, String fieldName)应用到某个类上。
在XStreamSample_01中添加如下代码:
代码语言:javascript复制static {
//设置类别名,默认为当前类名加上包名
xstream.alias("user", User.class);
//设置类成员名
xstream.aliasField("id", User.class, "userId");
xstream.aliasField("userName", User.class, "name");
}
XStream转换器:转换一些自定义类型
DateConverter.java
代码语言:javascript复制public class DateConverter implements Converter {
private Locale locale;
public DateConverter() {
this.locale = Locale.SIMPLIFIED_CHINESE;
}
public DateConverter(Locale locale) {
super();
this.locale = locale;
System.out.println("--有参数的构造方法--");
}
//判断要转换的类型
@Override
public boolean canConvert(Class arg0) {
return Date.class.isAssignableFrom(arg0);
}
//Java对象到XML转换逻辑
@Override
public void marshal(Object arg0, HierarchicalStreamWriter arg1,
MarshallingContext arg2) {
//getDateInstance(..):获取给定语言环境的给定格式化风格的日期格式器
DateFormat formatter = DateFormat.getDateInstance(DateFormat.DATE_FIELD, this.locale);
arg1.setValue(formatter.format(arg0));
}
//XML到Java对象转换
@Override
public Object unmarshal(HierarchicalStreamReader arg0,
UnmarshallingContext arg1) {
GregorianCalendar calendar = new GregorianCalendar();
DateFormat formatter = DateFormat.getDateInstance(DateFormat.DATE_FIELD, this.locale);
try {
calendar.setTime(formatter.parse(arg0.getValue()));
} catch (ParseException e) {
System.out.println(e.getMessage());
}
return calendar.getGregorianChange();//获得格里高利历的更改日期
}
}
调用:
代码语言:javascript复制static {
//创建一个XStream实例并指定一个XML解析器
xstream = new XStream(new DomDriver());
xstream.processAnnotations(LoginLog.class);
//注册自定义的日期转换器
xstream.registerConverter(new DateConverter(Locale.SIMPLIFIED_CHINESE));
}
问题:书上没有无参构造方法,但是我不定义无参构造方法会报错。并且如果我不在无参构造方法中初始化locale,在DateFormat formatter = DateFormat.getDateInstance(DateFormat.DATE_FIELD, this.locale);这名会报locale空指针。不知道什么原因。
XStream注解:
示例:
代码语言:javascript复制//别名注解,作用于类和字段
@XStreamAlias("loginLog")
public class LoginLog implements Serializable {
//忽略字段,作用于字段
@XStreamOmitField
private static final long serialVersionUID = 1L;
//转换为属性,作用于字段
@XStreamAsAttribute
@XStreamAlias("id")
private int loginLogId;
@XStreamAlias("userId")
private int userId;
@XStreamAlias("lastIp")
private String ip;
@XStreamConverter(DateConverter.class)
private Date loginDate;
public LoginLog() {}
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;
}
@Override
public String toString() {
return "用户 " userId " 最后一次登陆时间为:" loginDate;
}
}
启用XStream提供的注解功能,需要在执行Java对象与XML转换之前,先注册标注了XStream注解的Java对象。
代码语言:javascript复制xstream.processAnnotations(LoginLog.class);
//自动加载注解Bean
//xstream.autodetectAnnotations(true);
流化对象:
代码语言:javascript复制public class ObjectStreamSample {
private static XStream xstream = new XStream();
//Java对象转化为XML
public static LoginLog getLoginLog() {
LoginLog loginLog = new LoginLog();
loginLog.setLoginLogId(1);
loginLog.setUserId(1);
loginLog.setIp("192.168.1.1");
loginLog.setLoginDate(new Date());
return loginLog;
}
public void objectToXML() throws Exception {
LoginLog loginLog = ObjectStreamSample.getLoginLog();
//创建一个PrintWriter,用于输出
PrintWriter writer = new PrintWriter("D:\temporary\XStream\loginLog_02.xml");
//选用一个HierarchicalStreamWriter的实现类来创建输出
PrettyPrintWriter ppw = new PrettyPrintWriter(writer);
//CompactWriter cw = new CompactWriter(writer);
//创建对象输出流
ObjectOutputStream out = xstream.createObjectOutputStream(ppw);
out.writeObject(loginLog);
out.close();
}
//XML转化为Java对象
public LoginLog xmlToObject() throws Exception {
//通过对象流进行输入操作
FileReader reader = new FileReader("D:\temporary\XStream\loginLog_02.xml");
BufferedReader bufferedReader = new BufferedReader(reader);
//创建对象输入流
ObjectInputStream input = xstream.createObjectInputStream(bufferedReader);
//从XML文件中读取对象
LoginLog loginLog = (LoginLog)input.readObject();
return loginLog;
}
}
PrettyPrintWriter和CompactWriter的区别在于,用CompactWriter方法输出的为连续的没有分隔的XML文件,而用PrettyPrintWriter方法输出的为有分隔有一定格式的XML文件。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/219256.html原文链接:https://javaforall.cn