目的:将目标xml的内容解析到一个java对象里边(xml的各个标签有对应的java类,并且有包含关系)。
NginxCache配置文件:
<?xml version="1.0" encoding="utf-8"?>
XXXAction/getXXX.rdm
XXXBction/getXXX.rdm
XXXAction/getXXX.rdm
XXXBction/getXXX.rdm
<cache-evict>
<act pattern="XXXAction/addXXX.rdm" params="a,b">
<evict pattern="" methodRef="">
</evict>
<evict pattern="" methodRef="">
</evict>
</act>
<method id="" name="" class="" returnType="">
<param index="1" default="c"></param>
<param index="2" value="a"></param>
</method>
<method id="" name="" class="" returnType="">
<param index="1" default="c"></param>
<param index="2" value="a"></param>
</method>
</cache-evict>
对应的java类
具体设计思路:在解析到某个Element时调用 traverseOneElement(Element element,Object oneObj)方法;//element是遍历到对应的节点,oneObj是这个节点对应的对象。(刚开始只需要传一个确定的根类的对象即可)
在这个方法里遍历这个element的子节点,对每个子节点的element的Name用反射动态的创建对象,然后利用反射动态调用oneObj set方法,将对应的子节点对象set进去,然后,再调用
traverseOneElement(Element child_element,Object child_Obj);这样设计的, 第一次能设置成功,但是到第二次用子对象来get某个属性的时候会报这个错,不知道啥原因,请高手指教!!!
报错:
java.lang.IllegalArgumentException: object is not an instance of declaring class
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.iwint.rdm.utils.RDMPropertyUtil.getProperty(RDMPropertyUtil.java:60)
at com.iwint.rdm.nginxcache.bean.NginxCache.traverseOneElement(NginxCache.java:91) at com.iwint.rdm.nginxcache.bean.NginxCache.main(NginxCache.java:79)
package com.iwint.rdm.nginxcache.bean;
import java.util.Iterator;
import java.util.Map;
import org.apache.commons.collections.map.HashedMap;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import com.iwint.rdm.utils.Dom4jUtil;
import com.iwint.rdm.utils.RDMPropertyUtil;
/**
- @ClassName: NginxCache
- @Description: 解析NginxCache.xml用的标签类。
- @author yuanchangyou
-
@date 2013-9-27
*
*/
public class NginxCache {private static Map classAndBiaoqian;
private static NginxCache nginxCache=new NginxCache();
private Cacheable cacheable=new Cacheable();
private CacheEvict cacheEvict=new CacheEvict();
public NginxCache() {}
public Cacheable getCacheable() {
return cacheable;
}public CacheEvict getCacheEvict() {
return cacheEvict;
}public void setCacheable(Cacheable cacheable) {
this.cacheable = cacheable;
}public void setCacheEvict(CacheEvict cacheEvict) {
this.cacheEvict = cacheEvict;
}
public static NginxCache parseNginxCache() throws InstantiationException, IllegalAccessException, ClassNotFoundException{
//产生一个解析器对象
SAXReader reader = new SAXReader();
Document document = Dom4jUtil.parse2Document("D:/work/newEclipseWorkSpaces/rdm/src/main/resources/config/NginxCache.xml");
//获取文档的根元素
Element root = document.getRootElement();
NginxCache nginxcache=new NginxCache();
System.out.println(root.getName());
if(root.getName().equals("nginx-cache"))
//遍历节点
traverseOneElement(root,nginxcache);return null;
}
public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
classAndBiaoqian=new HashedMap();
classAndBiaoqian.put("nginx-cache", NginxCache.class.getName());
classAndBiaoqian.put("cacheable", Cacheable.class.getName());
classAndBiaoqian.put("pattern", UrlIPattern.class.getName());
classAndBiaoqian.put("cache-evict", CacheEvict.class.getName());
classAndBiaoqian.put("nginx-cache", Act.class.getName());
classAndBiaoqian.put("include","include");
classAndBiaoqian.put("exclude", "exclude");
// parseNginxCache();
SAXReader reader = new SAXReader();
Document document = Dom4jUtil.parse2Document("D:/work/newEclipseWorkSpaces/rdm/src/main/resources/config/NginxCache.xml");
//获取文档的根元素
Element root = document.getRootElement();
// NginxCache nginxcache=new NginxCache();
// if(root.getName().equals("nginx-cache"))
//遍历根节点
traverseOneElement(root,nginxCache);
}
public static void traverseOneElement(Element element,Object oneObj) throws InstantiationException, IllegalAccessException, ClassNotFoundException{
// if(element.getName().equals("nginx-cache")){}
Object chdil;
System.out.println(element.getName());
for( Iterator iter = element.elementIterator(); iter.hasNext();){
Element elmt=(Element) iter.next();
if(elmt.getName().equals("cacheable")||elmt.getName().equals("cache-evict")){
chdil=RDMPropertyUtil.createObjByName(classAndBiaoqian.get(elmt.getName()));
RDMPropertyUtil.setProperty(oneObj, elmt.getName(),chdil);
Object chidObj=RDMPropertyUtil.getProperty(oneObj, elmt.getName());
traverseOneElement(elmt, chidObj);
}
else if(elmt.getName().equals("include")||elmt.getName().equals("exclude")||elmt.getName().equals("act")||elmt.getName().equals("method")){
Object newchil=RDMPropertyUtil.getProperty(oneObj,classAndBiaoqian.get(elmt.getName()));
traverseOneElement(elmt, newchil);
}
else if(elmt.getName().equals("pattern")||elmt.getName().equals("param")){
}
}
}
}
package com.iwint.rdm.utils;
import java.lang.reflect.Method;
import java.lang.reflect.Field;
import java.beans.PropertyDescriptor;
public class RDMPropertyUtil {
public static PropertyDescriptor getPropertyDescriptor(Class clazz,
String propertyName) {
StringBuffer sb = new StringBuffer(); // 构建一个可变字符串用来构建方法名称
Method setMethod = null;
Method getMethod = null;
PropertyDescriptor pd = null;
try {
Field f = clazz.getDeclaredField(propertyName); // 根据字段名来获取字段
if (f != null) {
// 构建方法的后缀
String methodEnd = propertyName.substring(0, 1).toUpperCase()
+ propertyName.substring(1);
sb.append("set" + methodEnd); // 构建set方法
setMethod = clazz.getDeclaredMethod(sb.toString(),
new Class[] { f.getType() });
sb.delete(0, sb.length());// 清空整个可变字符串
sb.append("get" + methodEnd); // 构建get方法
// 构建get 方法
getMethod = clazz.getDeclaredMethod(sb.toString(),
new Class[] {});
// 构建一个属性描述器 把对应属性 propertyName 的 get 和 set 方法保存到属性描述器中
pd = new PropertyDescriptor(propertyName, getMethod, setMethod);
}
} catch (Exception ex) {
ex.printStackTrace();
}
return pd;
}
//动态调用obj对象的set方法(propertyName为属性名,value为值)
public static void setProperty(Object obj, String propertyName, Object value) throws InstantiationException, IllegalAccessException {
if(obj==null){
obj=obj.getClass().newInstance();
}
Class clazz = obj.getClass();// 获取对象的类型
PropertyDescriptor pd = getPropertyDescriptor(clazz, propertyName);
// 获取 clazz 类型中的 propertyName 的属性描述器
Method setMethod = pd.getWriteMethod();// 从属性描述器中获取 set 方法
try {
setMethod.invoke(obj, new Object[] { value });// 调用 set
// 方法将传入的value值保存属性中去
} catch (Exception e) {
e.printStackTrace();
}
}
//动态调用obj对象的get方法(propertyName为属性名)
public static Object getProperty(Object obj, String propertyName) throws InstantiationException, IllegalAccessException {
Class clazz = obj.getClass();// 获取对象的类型
// 获取clazz类型中的propertyName的属性描述器
PropertyDescriptor pd = getPropertyDescriptor(clazz, propertyName);
Method getMethod = pd.getReadMethod();// 从属性描述器中获取 get 方法
Object value = null;
try {
value = getMethod.invoke(clazz, new Object[] {});// 调用方法获取方法的返回值
} catch (Exception e) {
e.printStackTrace();
}
return value;// 返回值
}
//动态创建一个对象,classname 为该类的全名
public static Object createObjByName(String className) throws InstantiationException, IllegalAccessException, ClassNotFoundException{
return Class.forName(className).newInstance();
}
}