Just some sharing about java open source and life
  • Commons-Digester read xml to JavaBean

    日期:2010-04-17 23:43 | 作者:JavaChen | 分类目录:OpenSource
    107 views

    最近在做一个小项目,需要读取数据字典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的实现原理和解析方式,就寻找网上现成的例子,自己在电脑上实现了一遍,由于网上的例子大多都不详细,所以在测试的过程中不断出现一些异常,但又不知道问题出自哪里、如何解决 :cry:
    最后终于找到了一个比较详细的实例,呵呵
    以下是一个测试方法,其它的代码没有贴出,如有需要可以告诉我:

    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();
    		}
    	}
    }
    
    作者:JavaChen | 分类目录:OpenSource | 标签:
  • JFreeChart 生成饼状图

    日期:2010-04-10 13:59 | 作者:JavaChen | 分类目录:OpenSource
    1,006 views

    最近在准备面试的过程中,遇到一个关于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 »

    作者:JavaChen | 分类目录:OpenSource | 标签:
  • Ibatis in Practice

    日期:2010-03-23 09:36 | 作者:JavaChen | 分类目录:OpenSource
    230 views

    ibatis一种“半自动化”的ORM实现,可以很大程度的简化DAO的代码开发,对开发者屏蔽不同数据库的连接方法,让开发人员不必关注底层采用什么数据库连接,很好的实现了代码的耦合性,而且ibatis的数据库访问类还是线程安全的,支持事务管理。ibatis jar包代码小,配置简单上手容易,故花了点时间看了看ibatis。 Read More »

    作者:JavaChen | 分类目录:OpenSource | 标签:
  • 初涉Ant

    日期:2010-03-18 13:49 | 作者:JavaChen | 分类目录:OpenSource
    198 views

    之前写了一篇关于maven的文章,觉得maven过于复杂,而且现在项目中根本没有使用,所以只是简单的了解了以下。在了解maven的过程当中,发现了ant这一熟悉而又陌生的名称,网上还有一些关于maven和ant对比的文章。关于ant,每次打开myeclipse的时候总会看到他,却不知道他有什么作用,于是准备从ant开始,进而学习maven,再次学会利用maven构建自己的项目,就当作充实自己的技术面吧! Read More »

    作者:JavaChen | 分类目录:OpenSource | 标签:
  • How Velocity Works?

    日期:2010-03-17 15:21 | 作者:JavaChen | 分类目录:OpenSource
    90 views

    当在一个应用程序或是servlet中使用Velocity 的时候,通常有以下几个步骤:
    1.初始化Velocity ,Velocity有两种实例,一个是单例(Singleton )一个是每次运行时一个实例(separate runtime instance)。
    2.创造一个上下文环境(Context )对象。
    3.往Context 里增加对象。
    4.选择一个模板(template)。
    5.将模板和对象一起输出。 Read More »

    作者:JavaChen | 分类目录:OpenSource | 标签:
  • JSON-RPC-Java

    日期:2010-03-15 16:36 | 作者:JavaChen | 分类目录:OpenSource
    168 views

    以前为了在前台完成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 »

    作者:JavaChen | 分类目录:OpenSource | 标签:
  • 使用maven建立基本开发结构

    日期:2010-03-14 19:37 | 作者:JavaChen | 分类目录:OpenSource
    133 views

    在研究Struts2时候,看到用maven建立基本开发结构,感到很陌生,决定查查资料,熟悉maven,于是有了这篇入门文章熟悉maven的一些概念。由于最近的项目还没有用到maven,所以打算只是简单了解Maven,方便以后查阅之用。

    建议初学者看看这篇文章:http://holylin.javaeye.com/blog/25527 Read More »

    作者:JavaChen | 分类目录:OpenSource | 标签:
  • Xmappr开源项目研读

    日期:2010-01-26 22:29 | 作者:JavaChen | 分类目录:OpenSource
    105 views

    一个偶然的点击发现了一个使用纯Java编写的处理XML的类库,里面涉及了java底层的一些知识,包括反射、泛型、注释等等。决定从这个小框架的研究开始学习java jdk的底层知识。 Read More »

    作者:JavaChen | 分类目录:OpenSource | 标签:
回到顶部

无觅相关文章插件,快速提升流量