对于一些小批量的数据,如果采用数据库来存取的话,未免有点大题小作,使用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. Android 自定义Spinner和其下拉窗口

    : 自定义Spinner其实包括两个部分: 第一部分是用来打开下拉列表的按钮,如图,这个绿色背景直接设置Spinner的背景就行,素材文件如下: 里面的文字需要注意下,Spinner控件没有直接修改文 ...

  2. C程序中唯一序列号的生成

    在实际的软件开发项目中.常常会涉及唯一序列号的生成.本文以一个实际的程序为例,介绍了唯一序列号的生成过程. 本文生成的序列号的样式为:MMDDHHMINSS_XXXXXX. 程序例如以下: /**** ...

  3. linux mysql命令

    一: 1.启动 MySQL安装完成后启动文件mysql在/etc/init.d目录下,在需要启动时运行下面命令即可. /etc/init.d/mysql start 2.停止 /usr/bin/mys ...

  4. 在进行页面的DIV CSS排版时,遇到IE6(当然有时Firefox下也会偶遇)浏览器中的图片元素img下出现多余空白的问题绝对是常见的对于该问题的解决方法也是“见机行事”。

    当一个img标签没得图片时,在firox中,即使给img标签设置了固定高度和宽度,img标签还是不会站位: 解决方法一:直接将img设置为块状元素:即,设置img为“display:block;”.在 ...

  5. 动态代理与AOP

    1. 代理的分类: 静态代理:每个代理类只能为一个接口服务 动态代理:可以通过一个代理类完成全部的代理功能(由JVM生成实现一系列接口的代理类,即:生成实现接口的类的代理) 2. 动态代理: 在Jav ...

  6. PHP中的function函数详解

    PHP函数,在PHP中函数起到一个不可分割的重要部分,很多功能实现都要用到函数,PHP的最大的威力就来源于函数! 在PHP中内建函数至少有上千个函数.这些内建函数了解就行了,官方文档里面有函数大全:传 ...

  7. Java_Activiti5_菜鸟也来学Activiti5工作流_之入门简单例子(一)

    // VacationRequest.java /** * author : 冯孟活 ^_^ * dates : 2015年9月1日 下午10:32:58 * class : 演示简单的公司请假流程 ...

  8. 转 sqlserver字段描述相关操作sql

    可以自己查询系统表: SELECT o.name AS tableName, c.name AS columnName, p.[value] AS Description FROM sysproper ...

  9. classpath and path.

    simply talk about the <path> and the <classpath> in java development. when the <path& ...

  10. sql yog注册码

    Name: AnyRegistration Code: 26f359fc-e3f6-4727-8af1-72a1a4a0819d