为了满足系统的灵活性,有些功能经常需要用到配置文件,一般是xml格式的居多.如何能快速读写配置文件呢?

以前都是用dom4j提供的api来读写xml文件,用dom4j读写配置文件总感觉像是在结构化的处理问题,能不能直接把xml文件和JavaBean之间相互转换呢?答案肯定是可以,xstream中提供了很简单的方式将二者转化,感觉这样才像面向对象化处理问题.

xstream知识点简单总结:
1.JavaBean到xml,用toXML()方法;Xml到JavaBean,用fromXML()方法;
2.转换时别名映射:
  1)类别名,alias(String name, Class type)。 
  2)类成员别名,aliasField(String alias, Class definedIn, String fieldName) 
  3)类成员作为属性别名,aliasAttribute(Class definedIn, String attributeName, String alias)
  4)去掉JavaBean中某个字段不生成到xml中,omitField(definedIn, fieldName)
  5)去掉集合类型生成xml的父节点,addImplicitCollection(Class ownerType, String fieldName) 
  6)注册一个转换器,registerConverter(Converter converter)  
3.映射别名对应注解
  @XStreamAlias("xxx")
  @XStreamAsAttribute  
  @XStreamImplicit()或@XStreamImplicit(itemFieldName = "xxx")
  @XStreamOmitField
  @XStreamConverter(Class)

我比较倾向于使用注解来处理,这样只要修改JavaBean上的内容就可以了.
实体类Stdent,配置注解:

import com.thoughtworks.xstream.annotations.XStreamAlias;
@XStreamAlias("STUDENT")
public class Student {@XStreamAlias("NAME")private String name;@XStreamAlias("CLASS")private String classes;//get和set方法@Overridepublic String toString() {return "Student [classes=" + classes + ", name=" + name + "]";}
}

我觉得如果读不到配置文件就报错不太友好,为了程序健壮性考虑应该在读不到配置文件时生成一个默认的下次就能读到了.
第一版工具类:

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;public class XmlUtil1 {private static final String file = "student1.xml";//运行main方法后刷新整个工程可以找到student1.xmlpublic void saveConfig(Student entity) {System.out.println("===保存配置====");XStream stream = new XStream(new DomDriver("utf-8"));// xml文件使用utf-8格式stream.autodetectAnnotations(true);// 设置自动匹配annotation.try {FileOutputStream out = new FileOutputStream(file);stream.toXML(entity, out);// 将实体类转为xml并输出到文件.} catch (FileNotFoundException e) {e.printStackTrace();}}/*** 从配置文件中读取配置,并自动转换为对应的对象.* * @return Student*/public Student getConfig() {XStream stream = new XStream(new DomDriver("utf-8"));// xml文件使用utf-8格式stream.autodetectAnnotations(true);// 设置自动匹配annotation.FileInputStream input;Student entity;try {input = new FileInputStream(file);// 由于xstream-1.3.1.jar中有个bug,从xml文件中读出的内容autodetectAnnotations(true)不生效,必须用alias后才正常.stream.alias("STUDENT", Student.class);entity = (Student) stream.fromXML(input); // 从配置文件中读取配置,并自动转换为对应的对象} catch (FileNotFoundException e1) {entity = setDefaultConfig();// 文件不存在时创建一个默认的配置文件.saveConfig(entity);}return entity;}// 创建一个默认的配置文件,需重写private Student setDefaultConfig() {Student stu = new Student();stu.setName("李坤");stu.setClasses("五期提高班");return stu;}public static void main(String[] args) {XmlUtil1 util = new XmlUtil1();System.out.println(util.getConfig());}
}

当写了两三个配置文件之后发现有很多内容是重复的,读getConfig和写saveConfig的过程每个配置文件基本一致,只要修改一点点内容就行了.
    重构一下吧,以后修改的内容越少越好,考虑使用泛型(使用泛型的好处,把运行时错误带入到编译期发现),见下面的工具类以后不用修改读getConfig和写saveConfig的过程了,只需修改默认的配置文件setDefaultConfig()方法即可.所以形成了第二版工具类:
注:由于xstream-1.3.1.jar中有个bug,从xml文件中读出的内容autodetectAnnotations(true)不生效,必须用alias后才正常.

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.io.xml.DomDriver;/** 封装后的读写配置文件的工具类,可以将设置注解后的对象与xml转化. * 写入用saveConfig方法,读取用getConfig方法* * @author 李坤* * 使用步骤: * 1.引入工具类和xstream.jar* 2.修改文件名,可以用../代表上级文件夹路径.* 3.写一个类或几个类并配置xstream注解,用于对象和xml之间的转换.注意,一定要在需转化的实体类上设置注解.* 4.修改setDefaultConfig方法,本方法的作用是当配置文件找不到时自动生成一个默认的配置文件,提高程序的健壮性.* 5.修改main方法可进行测试,写入用saveConfig方法,读取用getConfig方法.* 6.还可以加一些自己的逻辑处理自己的业务的方法.*/
public class XmlUtil2<T> {private static final String file = "student2.xml";// 文件名,可以用../代表上级文件夹路径Class<T> clazz;public XmlUtil2(Class<T> clazz) {this.clazz = clazz;}/***保存xml文件* * @param entity*            xml文件对应的对象*/public void saveConfig(T entity) {System.out.println("===保存配置====");XStream stream = new XStream(new DomDriver("utf-8"));// xml文件使用utf-8格式stream.autodetectAnnotations(true);// 设置自动匹配annotation.try {FileOutputStream out = new FileOutputStream(file);stream.toXML(entity, out);// 将实体类转为xml并输出到文件.} catch (FileNotFoundException e) {e.printStackTrace();}}/*** 从配置文件中读取配置,并自动转换为对应的对象.* * @return T*/public T getConfig() {XStream stream = new XStream(new DomDriver("utf-8"));// xml文件使用utf-8格式stream.autodetectAnnotations(true);// 设置自动匹配annotation.FileInputStream input;T entity;try {input = new FileInputStream(file);String alias = "";if (clazz.isAnnotationPresent(XStreamAlias.class)) {alias = clazz.getAnnotation(XStreamAlias.class).value();}stream.alias(alias, clazz);// 由于xstream-1.3.1.jar中有个bug,从xml文件中读出的内容autodetectAnnotations(true)不生效,必须用alias后才正常.entity = (T) stream.fromXML(input); // 从配置文件中读取配置,并自动转换为对应的对象} catch (FileNotFoundException e1) {entity = setDefaultConfig();saveConfig(entity);// 文件不存在时创建一个默认的配置文件.}return entity;}// 创建一个默认的配置文件,需重写private T setDefaultConfig() {Student stu = new Student();stu.setName("李坤");stu.setClasses("五期提高班");T entity = (T) stu;return entity;}// 运行main方法可查看测试结果.public static void main(String[] args) {XmlUtil2<Student> util = new XmlUtil2<Student>(Student.class);System.out.println(util.getConfig());}
}

上面的工具类每次读写配置文件还是需要复制一份并修改一个方法,感觉又多余又违反了开闭原则,好吧,再重构一份出来,使用抽象类吧,子类继承父类并实现抽象方法,这样的好处是父类的方法以后完全不用修改了,需要读写一个新配置文件继承并实现抽象方法就行了,符合开闭原则.这样就有了第三版代码:

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.io.xml.DomDriver;/** 封装后的读写配置文件的工具类,可以将设置注解后的对象与xml转化. * 写入用saveConfig方法,读取用getConfig方法* * @author 李坤* * 使用步骤: * 1.引入工具类和xstream.jar* 2.写一个类或几个类并配置xstream注解,用于对象和xml之间的转换.注意,一定要在需转化的实体类上设置注解.* 3.写一个子类继承XmlUtil3类,并且实现抽象方法.* 4.文件名,可以用../代表上级文件夹路径.* 5.setDefaultConfig方法,本方法的作用是当配置文件找不到时自动生成一个默认的配置文件,提高程序的健壮性.* 6.修改main方法可进行测试,写入用saveConfig方法,读取用getConfig方法.* 7.还可以加一些自己的逻辑处理自己的业务的方法.*/
public abstract class XmlUtil3<T> {abstract String setFileName();abstract Class<T> setClazz();// 创建一个默认的配置文件,需重写abstract T setDefaultConfig();/***保存xml文件* * @param entity*            xml文件对应的对象*/public void saveConfig(T entity) {System.out.println("===保存配置====");XStream stream = new XStream(new DomDriver("utf-8"));// xml文件使用utf-8格式stream.autodetectAnnotations(true);// 设置自动匹配annotation.try {FileOutputStream out = new FileOutputStream(setFileName());stream.toXML(entity, out);// 将实体类转为xml并输出到文件.} catch (FileNotFoundException e) {e.printStackTrace();}}/*** 从配置文件中读取配置,并自动转换为对应的对象.* * @return T*/public T getConfig() {XStream stream = new XStream(new DomDriver("utf-8"));// xml文件使用utf-8格式stream.autodetectAnnotations(true);// 设置自动匹配annotation.FileInputStream input;T entity;try {input = new FileInputStream(setFileName());String alias = "";if (setClazz().isAnnotationPresent(XStreamAlias.class)) {alias = setClazz().getAnnotation(XStreamAlias.class).value();}stream.alias(alias, setClazz());// 由于xstream-1.3.1.jar中有个bug,从xml文件中读出的内容autodetectAnnotations(true)不生效,必须用alias后才正常.entity = (T) stream.fromXML(input); // 从配置文件中读取配置,并自动转换为对应的对象} catch (FileNotFoundException e1) {entity = setDefaultConfig();// 文件不存在时创建一个默认的配置文件.if (entity !=null) {saveConfig(entity);}}return entity;}
}
public class StuConfig3 extends XmlUtil3<Student>{@OverrideClass<Student> setClazz() {return Student.class;}@OverrideStudent setDefaultConfig() {Student stu = new Student();stu.setName("李坤");stu.setClasses("五期提高班");return stu;}@OverrideString setFileName() {return "student3.xml";}public static void main(String[] args) {StuConfig3 config = new StuConfig3();System.out.println(config.getConfig());}
}

感觉上一版中抽象方法太多了,继承一次需要实现三个抽象方法,能不能简化一下让类更易用呢?好吧,那就简化一下,因为文件名和泛型的真实类在上一版的抽象方法实现时只有一行代码return xxx;所以咱们可以拿它做文章,把它放到构造方法中,强制在构造这个类的时候初始化它们,OK,动手实现第四版代码:

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.io.xml.DomDriver;/** 封装后的读写配置文件的工具类,可以将设置注解后的对象与xml转化. * 写入用saveConfig方法,读取用getConfig方法* * @author 李坤* * 使用步骤: * 1.引入工具类和xstream.jar* 2.写一个类或几个类并配置xstream注解,用于对象和xml之间的转换.注意,一定要在需转化的实体类上设置注解.* 3.写一个子类继承XmlUtil3类,并且实现抽象方法.* 4.文件名,可以用../代表上级文件夹路径.* 5.setDefaultConfig方法,本方法的作用是当配置文件找不到时自动生成一个默认的配置文件,提高程序的健壮性.* 6.修改main方法可进行测试,写入用saveConfig方法,读取用getConfig方法.* 7.还可以加一些自己的逻辑处理自己的业务的方法.*/
public abstract class XmlUtil4<T> {// 创建一个默认的配置文件,需重写abstract T setDefaultConfig();private String file;private Class<T> clazz;public XmlUtil4(Class<T> clazz, String file) {this.clazz = clazz;this.file = file;String dirPath = file.substring(0, file.lastIndexOf("/"));File dirFile = new File(dirPath);if (!dirFile.exists()) {dirFile.mkdirs();}}/***保存xml文件* * @param entity*            xml文件对应的对象*/public void saveConfig(T entity) {System.out.println("===保存配置====");XStream stream = new XStream(new DomDriver("utf-8"));// xml文件使用utf-8格式stream.autodetectAnnotations(true);// 设置自动匹配annotation.try {FileOutputStream out = new FileOutputStream(file);stream.toXML(entity, out);// 将实体类转为xml并输出到文件.} catch (FileNotFoundException e) {e.printStackTrace();}}/*** 从配置文件中读取配置,并自动转换为对应的对象.* * @return T*/public T getConfig() {XStream stream = new XStream(new DomDriver("utf-8"));// xml文件使用utf-8格式stream.autodetectAnnotations(true);// 设置自动匹配annotation.FileInputStream input;T entity;try {input = new FileInputStream(file);String alias = "";if (clazz.isAnnotationPresent(XStreamAlias.class)) {alias = clazz.getAnnotation(XStreamAlias.class).value();}stream.alias(alias, clazz);// 由于xstream-1.3.1.jar中有个bug,从xml文件中读出的内容autodetectAnnotations(true)不生效,必须用alias后才正常.entity = (T) stream.fromXML(input); // 从配置文件中读取配置,并自动转换为对应的对象} catch (FileNotFoundException e1) {entity = setDefaultConfig();// 文件不存在时创建一个默认的配置文件.if (entity != null) {saveConfig(entity);}}return entity;}
}
public class StuConfig4 extends XmlUtil4<Student> {private static final String file = "student4.xml";public StuConfig4() {super(Student.class, file);}@OverrideStudent setDefaultConfig() {Student stu = new Student();stu.setName("李坤");stu.setClasses("五期提高班");return stu;}public static void main(String[] args) {StuConfig4 config = new StuConfig4();System.out.println(config.getConfig());}}

总结一下吧,重构的过程是体现一个程序员基本素质,知识上学到了xstream的基本使用,考虑问题时用到了:对象化的思想和思考方式,程序设计时健壮性的考虑,开闭原则,抽象类,继承和实现,泛型(使用泛型可以把运行时错误提前到编译期得到检查和处理),类也要求易用性等.

本例子的代码结构:

本例子的下载地址:http://download.csdn.net/detail/lk_blog/4806615

一次代码重构之旅-快速读写xml文件工具类封装相关推荐

  1. java读写excel文件poi_Java利用POI读写Excel文件工具类

    本文实例为大家分享了Java读写Excel文件工具类的具体代码,供大家参考,具体内容如下 package com.test.app.utils; import java.io.File; import ...

  2. java 写 xml 文件 工具类_XML读写工具类

    摘要:①读取XML文件,生成pojo对象:②将对象信息保存到xml中. 步骤: ①新建一个普通的java类BasePage: packagecom.test.selenium.pages;import ...

  3. (3)[wp7数据存储] WP7 IsolatedStorage系列篇——通过XmlSerializer读写XML文件 [复制链接]...

    发表于 2012-5-17 15:51:07 |只看该作者 |倒序浏览 分享到: 本帖最后由 agameboy 于 2012-5-17 17:08 编辑 这一篇我们会通过XmlSerializer读写 ...

  4. (vc)分享一个读写ini文件的类,支持多种数据类型的读写,二进制数据都能保存和读取...

    读写ini文件的类叫CIni,有ini.h和ini.cpp两个文件组成.     ini.h文件: #pragma once#define SER_GET(bGet,value) SerGet(bGe ...

  5. Unity(C#)读写xml文件详解

    目录 什么是xml文件? xml文件的结构 如何读写xml文件 什么是xml文件? xml文件是一种可拓展标记语言,由于简单易用,常被应用程序用于保存数据,unity也是如此,在我们需要控制读写用户的 ...

  6. Fixflow引擎解析(三)(模型) - 创建EMF模型来读写XML文件

    Fixflow引擎解析(四)(模型) - 通过EMF扩展BPMN2.0元素 Fixflow引擎解析(三)(模型) - 创建EMF模型来读写XML文件 Fixflow引擎解析(二)(模型) - BPMN ...

  7. 整理Python lxml读写xml文件详细教程

    Python lxml读写xml文件详细教程 xml文档解析 创建xml文档节点 更新xml文档节点 xml文档解析 下面展示详细解析过程. <?xml version='1.0' encodi ...

  8. dom4j读写xml文件

    dom4j读写xml文件 首先我们给出一段示例程序: import java.io.File; import java.io.FileWriter; import java.util.Iterator ...

  9. [转]C#读写xml文件

    c#读写xml文件 已知有一个XML文件(bookstore.xml)如下: <?xml version="1.0" encoding="gb2312"? ...

最新文章

  1. 中国首次纳米孔测序大会:不可错过的教学专场和技术诊断
  2. python txt文件读写(追加、覆盖)
  3. (二)Cacti监控
  4. 20155335俞昆 2017-2018-1 《信息安全系统设计》第9周学习总结
  5. Python+Appium+POM实现APP端自动化测试
  6. linux 复制包括子目录_【Linux分享】Linux常用命令+教程分享
  7. 【Java文件操作(七)】序列化:将自定义类写入文件
  8. icd植入是大手术吗_骨折手术植入了钢板,骨折痊愈后,需要取出钢板吗?
  9. Java对象内存布局
  10. matlab subplot(figure)如何设置使得图像最终显示出来不一样大小
  11. aes 结尾 特殊字符_九阳语文班同学分享第一季“开头结尾” ——首尾呼应
  12. 简单实用的 Ubuntu 快捷键
  13. python下载快手视频教程_python如何下载快手视频
  14. MindSpore,易用性提升的思考与实践
  15. 操作系统的启动与引导问题 BIOS、UEFI、MBR、GPT
  16. win10u盘被写保护怎么解除_win10系统中u盘被写保护怎么解除
  17. Power bi 3.10 折线和堆积柱形图
  18. python检验多重共线性_python从机器学习角度处理共线性
  19. 本地电脑无法登陆路由器
  20. win10计算机怎么打开方式,Win10如何还原打开方式?还原打开方式的方法

热门文章

  1. 世界上用户最多的两大星球丨腾讯赚钱花钱!脸谱道歉道歉!
  2. 影响网络购物公平 潜藏信息安全隐患
  3. 2014全国大学生赛事
  4. 色谱级免疫球蛋白——人IgG全分子相关研究
  5. 上古卷轴java怎么刷_上古卷轴5快速升级方法一览 教你如何快速升级
  6. Windows如何在CMD或PowerShell中配置代理,报错及解决方法
  7. 秒杀项目之网关服务限流熔断降级分布式事务
  8. python取两位小数点的函数_python中round函数保留两位小数的方法
  9. pdf2docx库 | 转文件格式,支持抽取文件中的表格数据
  10. 子类调用父类构造方法 java_JAVA子类调用父类构造方法