-
Commons-Digester read xml to JavaBean
最近在做一个小项目,需要读取数据字典XML中的内容取出相应的配置信息,在前台用Extjs生成一个查询框架,刚开始我是自己利用dom的开源lib以SAX的方式读数据字典,生成相应的java对象,但总感觉自己写的读取方法不是很完美,所以想在网上找找更好的解决办法。百度一下,看到了 Commons-Digester这个开源的jar文件,Digester本来仅仅是Jakarta Struts中的一个工具,用于处理struts-config.xml配置文件,后来就独立出来用于解析XML文件。
Digester由”事件”驱动,通过调用预定义的规则操作对象栈,将XML文件转换为Java对象。工作原理如下:
Digester底层采用SAX解析XML文件,所以很自然的,对象转换由”事件”驱动,即在识别出特定XML元素时(实际被细分为begin、 body、end、finish四个时点),将执行特定的动作,比如创建特定的Java对象,或调用特定对象的方法等。此处的XML元素根据匹配模式 (matching pattern)识别,而相关操作由规则(rule)定义。在转换过程中,Digester维持了一个对象栈,可以看作对象转换的工作台,用来存放转换中生成的、或是为转换临时创建的Java对象。对输入XML文件作了一趟完整的扫描后,对象栈的栈顶元素即为目标对象。由于Digester屏蔽了SAX解析的细节,使用者仅需关注转换操作本身,大大简化了转换操作。使用Digester,基本步骤如下:
1.创建Digester对象实例。
2.设置该Digester对象的配置属性(可选)。
3.将需要的初始对象 push到该Digester对象的对象栈上(可选)。
4.需要注册所有的XML元素匹配模式与处理规则之间的映射关系。
5.用 digester.parse()解析的XML文档对象,得到目标对象。在了解了Digester的实现原理和解析方式,就寻找网上现成的例子,自己在电脑上实现了一遍,由于网上的例子大多都不详细,所以在测试的过程中不断出现一些异常,但又不知道问题出自哪里、如何解决

最后终于找到了一个比较详细的实例,呵呵
以下是一个测试方法,其它的代码没有贴出,如有需要可以告诉我:package com.javachen.xml.digester; import java.io.File; import java.io.IOException; import org.junit.Test; import org.xml.sax.SAXException; import org.apache.commons.digester.Digester; import static org.junit.Assert.*; public class DigesterTest { /** * 属性方式 */ @Test public void testOne() { Digester digester = new Digester(); // 设置不进行合法性验证 digester.setValidating(false); // 当遇到<teacher>时创建一个Teacher对象,放入栈顶 digester.addObjectCreate("teacher", Teacher.class); digester.addSetProperties("teacher"); // 当遇到<teacher>的子元素<student>时创建一个Student对象,放入栈顶 digester.addObjectCreate("teacher/student", Student.class); // 设置<student>的属性值,根据属性值调用相应的set方法 digester.addSetProperties("teacher/student"); // 当再次遇到<student>时创建一个Student对象,放入栈顶, //同时调用栈次顶的addStudent方法 digester.addSetNext("teacher/student", "addStudent", "com.javachen.xml.digester.Student"); try { Teacher teacher = (Teacher) digester.parse(new File( "src/com/javachen/xml/digester/student.xml")); assertEquals(8, teacher.getStudents().size()); } catch (IOException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } } /** * 子标签方式(设置Property方式一) */ @Test public void testTwo() { Digester digester = new Digester(); digester.setValidating(false); // 设置栈顶 digester.push(new TeacherList()); digester.addObjectCreate("teachers/teacher", Teacher.class); digester.addSetProperties("teachers/teacher"); digester.addObjectCreate("teachers/teacher/student", Student.class); // digester.addSetProperties("teachers/teacher/student"); // 子标签方式设置属性方法之一,第三个参数是第二个参数所指方法的参数个数 digester.addCallMethod("teachers/teacher/student/name", "setName", 1); digester.addCallMethod("teachers/teacher/student/age", "setAge", 1); digester.addCallMethod("teachers/teacher/student/id", "setId", 1); digester.addSetNext("teachers/teacher/student", "addStudent", "com.javachen.xml.digester.Student"); digester.addSetNext("teachers/teacher", "addTeachers", "com.javachen.xml.digester.Teacher"); try { TeacherList teacher = (TeacherList) digester.parse(new File( "src/com/javachen/xml/digester/teacher.xml")); assertEquals(2, teacher.getTeachers().size()); assertEquals("java", teacher.getTeachers().get(0).getCourse()); assertEquals(8, teacher.getTeachers().get(0).getStudents().size()); } catch (IOException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } } /** * 子标签方式(设置Property方式二) */ @Test public void testThree() { Digester digester = new Digester(); digester.setValidating(false); // 设置栈顶 digester.push(new TeacherList()); digester.addObjectCreate("teachers/teacher", Teacher.class); digester.addSetProperties("teachers/teacher"); digester.addObjectCreate("teachers/teacher/student", Student.class); // 子标签方式设置属性方法之二 digester.addBeanPropertySetter("teachers/teacher/student/name"); digester.addBeanPropertySetter("teachers/teacher/student/age"); digester.addBeanPropertySetter("teachers/teacher/student/id"); digester.addSetNext("teachers/teacher/student", "addStudent", "com.javachen.xml.digester.Student"); digester.addSetNext("teachers/teacher", "addTeachers", "com.javachen.xml.digester.Teacher"); try { TeacherList teacher = (TeacherList) digester.parse(new File( "src/com/javachen/xml/digester/teacher.xml")); assertEquals(2, teacher.getTeachers().size()); assertEquals("java", teacher.getTeachers().get(0).getCourse()); assertEquals(8, teacher.getTeachers().get(0).getStudents().size()); } catch (IOException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } } /** * 子标签方式 (callMethod callParam方式) */ @Test public void testFour() { Digester digester = new Digester(); digester.setValidating(false); digester.push(new TeacherList()); digester.addObjectCreate("teachers/teacher", "com.javachen.xml.digester.Teacher"); digester.addSetProperties("teachers/teacher"); // 当<student>时调用栈顶元素(Teacher)的addStudents却并不执行, //等待addCallParam设置参数,3为参数个数,这里传入的参数是字符串。 digester.addCallMethod("teachers/teacher/student", "addStudent", 3); digester.addCallParam("teachers/teacher/student/name", 0); digester.addCallParam("teachers/teacher/student/age", 1); // 这句之后即</student>才调用addStudents方法,并且如果再次遇到<student>重复。 digester.addCallParam("teachers/teacher/student/id", 2); digester.addSetNext("teachers/teacher", "addTeachers", "com.javachen.xml.digester.Teacher"); try { TeacherList teacher = (TeacherList) digester.parse(new File( "src/com/javachen/xml/digester/teacher.xml")); assertEquals(2, teacher.getTeachers().size()); assertEquals("java", teacher.getTeachers().get(0).getCourse()); assertEquals(8, teacher.getTeachers().get(0).getStudents().size()); assertEquals("李世民2", teacher.getTeachers().get(1).getStudents() .get(2).getName()); } catch (IOException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } } }没有评论 -
JFreeChart 生成饼状图
最近在准备面试的过程中,遇到一个关于JFreeChart的复试题目,需要用JFreeChart做一个报表出来,具体题目内容待我实现之后在贴出来。周末闲着没事做,决定写写代码,熟悉JFreeChart的相关操作。
花了点时间,看看JFreeChart的API,利用JFreeChart jar包可以绘制pie charts 饼图,bar charts 柱状图,line and area charts曲线图,scatter plots and bubble charts 散列图,time series 时序图,Area Charts区域图,Difference Chart差异图,Step Chart步骤图,Multiple Axis Charts 混合图,Gantt charts甘特图,combination charts 复合图. Read More » -
Ibatis in Practice
ibatis一种“半自动化”的ORM实现,可以很大程度的简化DAO的代码开发,对开发者屏蔽不同数据库的连接方法,让开发人员不必关注底层采用什么数据库连接,很好的实现了代码的耦合性,而且ibatis的数据库访问类还是线程安全的,支持事务管理。ibatis jar包代码小,配置简单上手容易,故花了点时间看了看ibatis。 Read More »
-
初涉Ant
之前写了一篇关于maven的文章,觉得maven过于复杂,而且现在项目中根本没有使用,所以只是简单的了解了以下。在了解maven的过程当中,发现了ant这一熟悉而又陌生的名称,网上还有一些关于maven和ant对比的文章。关于ant,每次打开myeclipse的时候总会看到他,却不知道他有什么作用,于是准备从ant开始,进而学习maven,再次学会利用maven构建自己的项目,就当作充实自己的技术面吧! Read More »
-
How Velocity Works?
当在一个应用程序或是servlet中使用Velocity 的时候,通常有以下几个步骤:
1.初始化Velocity ,Velocity有两种实例,一个是单例(Singleton )一个是每次运行时一个实例(separate runtime instance)。
2.创造一个上下文环境(Context )对象。
3.往Context 里增加对象。
4.选择一个模板(template)。
5.将模板和对象一起输出。 Read More » -
JSON-RPC-Java
以前为了在前台完成JavaScript对后天代码的调用,用的是DWR框架,今天发现使用JSON-RPC-Java也可以实现DWR所实现的功能。
JSON-RPC-Java是一个用Java来实现动态JSON-RPC的框架. 利用它内置的一个轻级量JSON-RPC JavaScripIt客户端,可以让你透明地在JavaScript中调用Java代码。JSON-RPC-Java可运行在Servlet容器中如 Tomcat也可以运行在JBoss与其它J2EE应用服务器中因此可以在一个基于JavaScript与DHTML的Web应用程序中利用它来直接调用普通Java方法与EJB方法。 Read More » -
使用maven建立基本开发结构
在研究Struts2时候,看到用maven建立基本开发结构,感到很陌生,决定查查资料,熟悉maven,于是有了这篇入门文章熟悉maven的一些概念。由于最近的项目还没有用到maven,所以打算只是简单了解Maven,方便以后查阅之用。
建议初学者看看这篇文章:http://holylin.javaeye.com/blog/25527 Read More »
-
Xmappr开源项目研读
一个偶然的点击发现了一个使用纯Java编写的处理XML的类库,里面涉及了java底层的一些知识,包括反射、泛型、注释等等。决定从这个小框架的研究开始学习java jdk的底层知识。 Read More »