对于一些小批量的数据,如果采用数据库来存取的话,未免有点大题小作,使用XML文件是个不错的方法,尤其是在一些Web应用中,经常需要缓存一部分数据,如果将这些数据形成XML文件,解析后放入一个Hashtable,那就能大大加快访问的速度。

由于工作的需要,写了一个解析工具,将XML解析成相应的对象列表。以下是源代码,希望对大家有所帮助,更希望大家帮我来改进这个工具。

package com.sp.util;

/*
* author:hingwu
* email:hing3@163.com
* QQ:550598
* MSN:hing3wu@hotmail.com(很少开)
*/
import java.io.FileInputStream;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Date;
import java.util.List; import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList; import exceptions.MyException; public class ParseXMLToObject {
public ParseXMLToObject(){} @SuppressWarnings("unchecked")
public List getObject(String name,String path,String className){
DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
dbf.setIgnoringElementContentWhitespace(true);
DocumentBuilder db=null;
Document doc=null;
InputStream is=null;
try {
List list=new ArrayList();
db=dbf.newDocumentBuilder();
is=new FileInputStream(this.getClass().getResource(path).getPath());
doc=db.parse(is);
//根据要取的对象名称获取相应的节点列表
NodeList nodes=doc.getElementsByTagName(name);
if(nodes==null){
throw new MyException("null nodes with tagName "+name);
}
for(int i=0;i<nodes.getLength();i++){
Element node=(Element) nodes.item(i);
Class cls=Class.forName(className);
Object obj=cls.newInstance();
//获取节点下的所有子节点
NodeList childs=node.getChildNodes();
if(childs==null){
throw new MyException("null childs! "+node);
}
for(int j=0;j<childs.getLength();j++){
if(!childs.item(j).getNodeName().equals("#text")){
Element child=(Element)childs.item(j);
String childName=child.getNodeName();
String type=child.getAttribute("type");
String value=child.getAttribute("value");
Object valueObj=typeConvert(type,value);
String methodName="set"+Character.toUpperCase(childName.charAt(0))+childName.substring(1);
System.out.println("methodName="+methodName+", class="+Class.forName(type));
Method method=cls.getMethod(methodName, Class.forName(type));
method.invoke(obj, new Object[]{valueObj});
} }
list.add(obj);
}
return list; } catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
} }

//此方法用于将一个字符串转换为相应的数据类型
@SuppressWarnings("deprecation")
public Object typeConvert(String className,String value){
if(className.equals("java.lang.String")){
return value;
}
else if(className.equals("java.lang.Integer")){
return Integer.valueOf(value);
}
else if(className.equals("java.lang.Long")){
return Long.valueOf(value);
}
else if(className.equals("java.lang.Boolean")){
return Boolean.valueOf(value);
}
else if(className.equals("java.util.Date")){
return new Date(value);
}
else if(className.equals("java.lang.Float")){
return Float.valueOf(value);
}
else if(className.equals("java.lang.Double")){
return Double.valueOf(value);
}else return null;
}
} Subject类的代码: package com.sp.pojo; public class Subject {
private String port;
private String servletName;
public String getPort() {
return port;
}
public void setPort(String port) {
this.port = port;
}
public String getServletName() {
return servletName;
}
public void setServletName(String servletName) {
this.servletName = servletName;
}
public Subject(){}
@Override
public String toString() {
// TODO Auto-generated method stub
return port+","+servletName;
} }
附上我的XML文件

<?xml version="1.0" encoding="UTF-8"?>
<xml-body>
<subjects>
<port type="java.lang.String" value="4587"/>
<servletName type="java.lang.String" value="com.sp.servlets.Route" />
</subjects> <subjects>
<port type="java.lang.String" value="5687"/>
<servletName type="java.lang.String" value="com.sp.servlets.Route" />
</subjects> <security>
<userName type="java.lang.String" value="gogo"/>
<password type="java.lang.String" value="gogo" />
</security>
</xml-body> 自己写了一个测试类进行测试 /**
* author:hingwu
* email:hing3@163.com
* QQ:550598
* MSN:hing3wu@hotmail.com(很少开)
*
* 上午11:44:27
*/
package com.sp.test; import java.util.Iterator;
import java.util.List; import com.sp.util.ParseXMLToObject; public class TestParse {
public static void main(String[] args){
ParseXMLToObject pxt=new ParseXMLToObject();
// List list=(List)pxt.getObject("security","/cache.xml","com.sp.pojo.Security");
List list=(List)pxt.getObject("subjects","/cache.xml","com.sp.pojo.Subject");
Iterator it=list.iterator();
while(it.hasNext()){
System.out.println(it.next());
} }
} 由于我的这个工具主要是为了缓存数据来使用的,我同时还完成了缓存类Cache的代码: package com.sp.util; import java.io.File;
import java.util.Hashtable; public class Cache {
//cache用来放置各种需要缓存的数据
private static Hashtable cache=new Hashtable();
//lastModifyTime用于维护配置文件的最后修改时间,从而确定是直接从Cache读数据还是需要重新解析配置文件
private static long lastModifyTime; public Object getObject(String name,String path,String parseClass,String className){
//如果配置文件被修改过则直接解析文件,否则直接从cache中取得相应的对象
if(checkModifyTime(path)){
System.out.println("get Object from file");
return getObjectFromFile(name,path,className);
}
return getObjectFromCache(name);
} //直接从缓存中获取相应的对象
public Object getObjectFromCache(String name){
System.out.println("get Object from cache");
return cache.get(name);
} //解析配置文件获取相应的对象
@SuppressWarnings("unchecked")
public Object getObjectFromFile(String name,String path,String className){
String key="key";
synchronized(key){
ParseXMLToObject pxt=new ParseXMLToObject();
Object obj=pxt.getObject(name, path, className);
cache.put(name, obj);
return obj;
} } //判断配置文件是否被修改过
public boolean checkModifyTime(String path){
String absPath=this.getClass().getResource(path).getPath();
long time=(new File(absPath)).lastModified();
if(lastModifyTime==0L||time>lastModifyTime){
lastModifyTime=time;
return true;
}
return false;
}
} 每次通过Cache去获取Hashtable中的数据时,会先判断XML文件有没有被修改过,如果没有修改,则直接返回数据,有修改则解析XML文件后返回数据。 为了测试Cache类,专门写了一个Test类: /**
* author:hingwu
* email:hing3@163.com
* QQ:550598
* MSN:hing3wu@hotmail.com(很少开)
*
* 下午02:04:10
*/
package com.sp.test;
import java.util.Iterator;
import java.util.List; import com.sp.util.Cache; public class TestCache { /**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
for(int i=0;i<10;i++){
System.out.println("第"+i+"次获取缓存数据:");
Cache cache=new Cache();
List list=(List)cache.getObject("subjects","/cache.xml", "com.sp.util.ParseXMLToObject", "com.sp.pojo.Subject");
Iterator it=list.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} } } 这种缓存策略有个好处,那就是在应用运行的时候,我们可以随时修改XML文件,而不需要重启应用或重新布署。

利用Java反射机制完成XML到对象的解析的更多相关文章

  1. 利用java反射机制 读取配置文件 实现动态类载入以及动态类型转换

    作者:54dabang 在spring的学习过程之中,我们能够看出通过配置文件来动态管理bean对象的优点(松耦合 能够让零散部分组成一个总体,而这些总体并不在意之间彼此的细节,从而达到了真正的物理上 ...

  2. 利用JAVA反射机制设计通用的DAO

    利用JAVA反射机制设计一个通用的DAO 反射机制 反射机制指的是程序在运行时能够获取自身的信息.在java中,只要给定类的名字,    那么就可以通过反射机制来获得类的所有信息. 反射机制创建类对象 ...

  3. 利用Java反射机制对实体类的常用操作工具类ObjectUtil

    代码: ObjectUtil类: import java.lang.reflect.Field; import java.math.BigDecimal; import java.text.Simpl ...

  4. 【java】java反射机制,动态获取对象的属性和对应的参数值,并属性按照字典序排序,Field.setAccessible()方法的说明【可用于微信支付 签名生成】

    方法1:通过get()方法获取属性值 package com.sxd.test.controller; public class FirstCa{ private Integer num; priva ...

  5. 利用Java反射机制将Bean转成Map

    import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang ...

  6. 利用java反射机制实现读取excel表格中的数据

    如果直接把excel表格中的数据导入数据库,首先应该将excel中的数据读取出来. 为了实现代码重用,所以使用了Object,而最终的结果是要获取一个list如List<User>.Lis ...

  7. 利用JAVA反射机制将JSON数据转换成JAVA对象

    net.sf.json.JSONObject为我们提供了toBean方法用来转换为JAVA对象, 功能更为强大,  这里借鉴采用JDK的反射机制, 作为简单的辅助工具使用,   有些数据类型需要进行转 ...

  8. 不使用BeanUtils,利用Java反射机制:表单数据自动封装到JavaBean

    在百度搜“java反射 将表单数据自动封装到javabean ”,第一页显示的都是一样的代码,都是利用导入第三方jar包<commons-beanutils>和<commons-lo ...

  9. Java反射机制(创建Class对象的三种方式)

    1:了解什么是反射机制? 在通常情况下,如果有一个类,可以通过类创建对象:但是反射就是要求通过一个对象找到一个类的名称:   2:在反射操作中,握住一个核心概念: 一切操作都将使用Object完成,类 ...

随机推荐

  1. Java多线程之释放对象的锁

          由于等待一个锁定线程只有在获得这把锁之后,才能恢复运行,所以让持有锁的线程在不需要锁的时候及时释放锁是很重要的.在以下情况下,持有锁的线程会释放锁: 1. 执行完同步代码块. 2. 在执行 ...

  2. Java基础知识强化之集合框架笔记21:数据结构之 数组 和 链表

    1. 数组 2. 链表

  3. enter 默认搜索

    onkeydown=" if(event.keyCode==13) Search(); "

  4. PHP面向对象的基本写法(区别于java)

    <?php /** * 这是一个人的对象 */ class ClassName { public $name; public $age; public $sex; public static $ ...

  5. List转xml

    1. List<Model> list = new List<Model>(); Model zj = new Model(); zj.id = ; zj.name = &qu ...

  6. 读取xml字符串

    string strXml = @"<MessageData><pm_id>10</pm_id><pm_title>这是公司或者产品的名称&l ...

  7. ASP.NET和支付宝合作开发第三方接口的注意事项

    最近公司和支付宝合作开发第三方接口的项目,这里把过程中需要注意的地方说明一下: 前提:一般来说单个银行不接收个人或私企开通支付接口.因此,和第三方支付公司合作,签订合约开放接口就是通行的做法. 流程: ...

  8. C#中的Dictionary字典类介绍

      Dictionary字典类介绍 必须包含名空间System.Collection.Generic    Dictionary里面的每一个元素都是一个键值对(由二个元素组成:键和值)    键必须是 ...

  9. 多线程lock(instance)中instance的选择.

    如我的提问:http://bbs.csdn.net/topics/390496351?page=1#post-394837834 拥有类原子功能的类: class ShareState { //原子功 ...

  10. svn的初级使用

    首先呢 你需要下载一个软件  比如说是 Cornerstone. 进行安装好之后 然后 然后输入账号密码 就可以了 然后去xcode去进行相关的配置 点击第二个进入 偏好设置 点击最下边的+ 点击第二 ...