APP下载

基于J2EE的Web信息系统开发方法的定义

2012-11-25陈景霞

制造业自动化 2012年16期
关键词:单元测试配置文件数据源

陈景霞,李 萌

CHEN Jing-xia,LI Meng

(陕西科技大学 电气与信息工程学院,西安 710021)

0 引言

随着互联网技术的发展和普及,越来越多的复杂动态空间非线性分析系统的软件工具开始使用基于Web的网络平台实现用户界面、科学分析、信息处理、分发数据结果、行业专家跨地域信息交换和共享等功能。其中,对非线性分析模拟系统软件基于web平台的实时访问正成为网络应用系统中很重要的一部分。飞速发展的网络硬件和软件技术为web应用开发提供了更多的选择方案。因而,合理的选择和开发web平台对于非线性分析系统及其应用显得越来越重要。Web开发现阶段涌现出了许多优秀的开源框架,将web开发提升到一个更高的水平[1]。但是在某些情况下,开源框架并不能直接为常见的问题提供解决办法,开发者往往需要在开源框架基础上构建自己的开发框架。在分析现有几种开源框架特性和用法的基础上,本文研究一种新型的基于J2EE的开源框架组合,并定义了加强几种开源框架协同工作的技术体系和方法,有效的提高了web系统定制开发与集成的效率。

开发web应用项目时,通常有一些共同的设计问题需要考虑,如表现层、业务层、数据访问层的设计以及系统测试等等,甚至围绕个别独特功能性需求也会使用一些共同的设计模式,这就不可避免的会出现开发框架与设计模式的重用[2]。本文描述一种定制的J2EE框架(Customized J2EE Web-based Framework,简称CJW架构),它能够识别一般web应用开发的共同设计要素,提供从用户表现层到数据层一整套web应用开发模式、工具和实践方法。该框架基于Struts、Spring、Hibernate和JUnit等开源框架和工具进行构建和开发,可以进行灵活定制以满足各种Web项目的开发需求。

1 CJW架构关键技术

1.1 代码和配置信息的分离

Web应用程序的设计需要考虑诸如表现层、业务逻辑、数据存取和安全性等多个层面的因素,将不同的设计任务分解到不同的层次能够有效降低系统代码的耦合度,提高系统的可维护性,也便于采用好的设计模式,为特定设计层选择专用的开发工具和技术。同时,将一个项目进行层次划分会导致各层之间存在相互依赖。例如,一个简单的包含数据输入和查询功能的用例,只有将表现层的用户界面、查询逻辑代码和数据库存取代码结合起来才能实现所需要的功能,因此,需要定义一种好的策略来管理各层之间的依赖关系。

本文开发的CJW架构使用Spring框架将设计模式、可复用的代码和配置文件结合起来[3],通过控制反转(IOC)技术实现系统各层的松耦合,通过IOC容器管理各个对象之间的依赖关系,能够有效避免硬性编码造成的耦合过于紧密的状况;使用依赖注入(Dependency Injection,DI)技术实现逻辑相关代码的松耦合,依赖注入是由框架或容器将被调用类注入给调用对象,以此来消除对象和被调用类之间的依赖关系,具体实现形式包括构造函数注入,设值方法注入和接口注入[4]。同时,Spring框架提供的面向切面编程(AOP)方法,通过方法拦截可以轻松的实现诸如事务管理、日志管理、性能监控、安全检测等关注点编程。方法拦截是Spring AOP的一个重要概念,通过JDK动态代理机制实现,使开发人员能够更加专注于业务逻辑的实现[5]。

CJW架构包括两个部分:代码和配置信息。代码在特别的应用层中负责解决某个特定的问题,如与数据库的连接和交互、屏幕端的数据显示等。而配置文件则负责将应用的各个层连接起来。将配置信息从代码中分离出来不仅可以单独对配置信息进行管理,也可以灵活地将不同的配置信息应用于相同的底层代码。例如,一个数据库访问对象(DAO)能够使用JDBC接口通过某个数据源连接数据库,但它并不清楚这个数据源的连接信息究竟是从JNDI上下文中获取的,还是通过数据库驱动管理器获取的,该数据源可以连接远程数据库,也可以连接本地数据库。无论这个数据源如何定义,DAO都能以相同的方式调用它。同样,一个服务对象(Service)可以用相同的模式调用一个DAO而不必知道该DAO是使用Hibernate或是Web服务实现,还是直接通过JDBC实现的。

CJW架构通过一组XML文件描述、管理整个应用的上下文配置信息,这些配置文件的逻辑集合就构成了整个应用的配置集合。在基于J2EE的企业级应用开发过程中,系统框架对数据源和JNDI等外部资源的使用通常在标准配置中定义,但可能会遇到如下问题:1)数据库的数据还没有被完全加载时,开发人员想要测试其中某种类型数据的显示结果,导致这部分测试工作无法进行。2)某些Service服务类或DAO还没有完成开发,那么与此相关的代码集成和测试就会阻碍整个开发的进程。

针对上述问题,本文提出的CJW架构采用一种专门面向开发的配置集合代替传统的配置方法,使开发人员不必担心那些与紧迫开发需求无关的外部系统是否可用。CJW架构定义了两个配置集合:默认配置和模块配置,基于这两种配置和特定的项目需求,开发者也可以增加额外的配置文件来定制自己的应用架构。默认配置使用JNDI定义的数据源与开发数据库建立连接,并且调用已经完全开发好的Service和DAO对象。而灵活的开发环境则是由模块配置集合搭建的,这些配置集合具备以下功能:1)可以连接本地数据库,或是通过DriverManagerDataSource驱动程序管理器连接开发数据库;2)使用Spring框架的DataSourceTransactionManager进行本地事务管理;3)调用完全开发好的应用Service和DAO对象;4)使整个基于Spring框架的应用上下文能够在应用服务器外部进行完整的运行和测试。

CJW架构的配置集合包括service和Web两部分:Service部分定义各种服务接口和实现(即services)、数据库访问对象接口和实现(即DAOs)以及服务和整合层用到的各种资源;Web部分主要为表现层定义各种显示组件。这两部分对于一个完整的配置集合缺一不可。CJW架构的配置集合由Spring框架的beanRefContext.xml和applicationContextMapping.properties等配置文件化合而成。其中,beanRefContext.xml文件定义了所有配置集合的services,它通常位于项目的src/config目录下,不同配置集合共享的应用上下文文件也位于这个目录下。此外,每一个模块配置集合都有自己的子目录,其下包含自己的相关文件。在XML文件中使用

1.2 类与依赖关系的设计

配置好上述CJW架构之后,接下来的编码与整体构造工作包括:开发相应的用户端界面;设计相应的Action类、ActionForm类和validation.xml输入校验组件;设计服务层service接口和实现类;设计数据访问层DAO接口和实现类;管理各个类之间的依赖关系。在开发一个实际用例时,弄清楚上述这些类的详细需求和彼此之间的依赖关系非常重要。

1.3 测试技术

测试应该是整个开发过程中不可或缺的一部分。对于本文提出的CJW框架而言,单元测试是指基于JUnit框架[6]实现的对服务层或整合层中每个类所进行的测试,其目的是确保类中封装的方法结合其它组件运行时能实现预期的功能。表现层的Action类通常不需要进行单元测试。与单元测试不同,集成测试需要代码之间的相互依赖,其目的是确保不同开发者开发的类联合运行时能实现预期的功能。而功能测试的重点则要针对每种可能出现的情况设计测试数据,并用这些数据测试应用的功能性,包括使用不同的数据对服务层的类进行功能测试,或者用真实的依赖关系对用户界面层进行功能测试。

为了进行不同类型的测试,首先要确保开发的应用程序是可测试的,一个可测试的应用需要具备以下基本特征:1)系统开发要便于进行单元测试和集成测试,应该在没有必须数据源或创建队列的情况下就能进行单元测试,测试时应该能够模拟代码之间的依赖性。2)为了进行功能测试,应用设计要便于模拟各种可能的测试情况。3)便于在应用的整个生命周期反复的运行所有测试。4)测试代码和应用代码划分清楚,互不干扰。将表现层、服务层和数据访问层的设计相分离的良好系统架构,对于设计一个可测试的应用非常重要。本文开发的CJW架构将更有利于设计出可测试的应用系统:首先提供了测试模板类有助于创建单元测试;整个应用的配置更加灵活便于适应各种测试需要;能够像任何JUnit测试那样进行单元测试,简单方便。CJW架构中还专门开发了默认的Ant编译脚本,在生成EAR文件时可以被调用对系统进行单元测试,也可以单独运行完成单元测试。

1.4 Web表现层的设计

本文开发的CJW架构使用Struts框架和JavaScript技术实现系统的表现层逻辑,处理应用程序与客户端的交互问题,并且为项目的扩展提供附加的技术支持。应用Struts框架进行开发时,首先要在web.xml文件中建立Action Servlet,然后在struts-config.xml文件中设置action mappings、formbeans以及页面重定向;最后在validation.xml文件中设置数据校验规则,对用户输入数据的合法性进行检查。为了使开发者不必频繁的编辑struts-config.xml或者validation.xml,CJW架构对上述方法进行了改进,使开发者在Action类和ActionForm类中应用XDoclet注释进行配置说明,注释信息在运行Ant脚本时能自动转换成strutsconfig.xml和validation.xml配置文件。

CJW架构设计了一个默认的Action模板类,使表现层的设计达到以下目标:1)每个JSP页面都对应一个唯一的Action处理类,一个Action类负责对一个单一的web页面进行处理。2)在Action类和ActionForm类中使用XDoclet注释对类之间的依赖关系及合法性校验规则进行说明。3)尽量避免或减少使用session会话对象,否则会降低系统的可伸缩性。然后,遵循以下步骤开发一个web页面:1)创建一个新的JSP页面,其中包含一个名为“actionType”的默认隐藏域,用来表示用户希望对该页面进行的处理类型。2)通过继承Action模板类创建一个新的Action类,必须说明该Action类与ActionForm中“actionType”隐藏域所表示处理方法的对应关系,然后在Spring配置文件中声明访问这个Action类的条件。3)创建一个新的ActionForm类并使用XDoclet注释说明表单数据的有效性校验规则。一旦JSP、Action以及ActionForm创建完成,必须运行Ant脚本重新生成struts-config.xml配置文件。

1.5 数据库存取

基于CJW架构开发的应用程序支持直接使用JDBC和Hibernate框架与关系数据库建立持久连接和数据通信,在必要的Spring上下文文件中进行配置即可。直接使用JDBC访问数据库的DAO类必须继承Spring框架的JdbcDaoSupport.java类;使用Hibernate框架访问数据库的DAO类必须继承Spring框架的HibernateDaoSupport.java类。

1.6 通过注释进行配置

CJW架构使用Spring框架来维护代码之间的依赖性。例如,Action类和ActionForm之间的依赖性在struts-config.xml文件中配置,而Service类和DAO类之间的依赖性在Spring应用上下文文件applicationContext.xml中配置。在同一个开发小组中这些配置文件被所有开发者共享,这可能导致配置文件的版本冲突。CJW架构提供了一种新型有效的方法,即XDoclet注释来说明类之间的依赖性,这种注释的方法不仅简化了系统的配置,而且能有效避免配置文件的版本冲突。

2 CJW架构的服务体系

本文开发的CJW架构提出使用简单的JavaBeans(即POJOs)实现业务逻辑,而业务逻辑必须以接口的形式进行声明,所有的Service实现类必须实现一个或多个业务接口,并且建议当服务层出现业务逻辑错误时能抛出定制的异常。CJW架构采用基于Spring框架的面向方面编程(AOP)的方式实现事务管理。同时,CJW架构很好地将面向服务用户的部署接口与面向业务逻辑的服务接口相分离。部署接口是一种可以用Web服务定义语言(WSDL)描述的外部接口,这类接口的实现类通常必须将请求委托给实现服务接口的类。服务接口则是表示业务逻辑的Java接口,这样能确保所有的业务逻辑在业务层的一个固定类中进行定义和维护。部署接口中通常会包含服务接口中的若干方法。

Apache Axis 1.2.4框架是目前流行的标准Web服务架构。开发Web服务有两种不同的方法[7]:契约在前和契约在后,这两者之间的区别在于WSDL是在编码之前创建的,还是从写好的代码中产生的。如果服务的消费者和提供者都是使用各自不同技术(如.NET或Java)去实现Web服务的供应商,那就适合采用契约在前的方法开发Web 服务[10]。

3 中间层的整合

CJW架构在业务逻辑中间层采用相关技术实现与数据库、Web服务等外部资源的整合,其整合的目标在于:1)将基于JDBC或Hibernate的数据库访问操作封装在数据访问对象(DAO)中;2)尽可能简化对Web服务的调用;3)所有外部数据向应用域对象的转换操作应该限制在这一层进行;4)这一层中的单元测试类要设计简单且易于执行。

CJW架构支持使用Spring框架的JdbcTemplate和HibernateTemplate模板类访问关系数据库。当直接使用JDBC访问关系数据库时,应用中的DAO对象可以继承Spring框架的JdbcDaoSupport类,该类管理着访问数据库要用到的各种资源(例如预处理语句对象PreparedStatement等)。CJW架构可以通过应用配置文件将数据源插入到DAO类中。当使用Hibernate时,同样可以通过应用配置文件将Hibernate的SessionFactory注入到DAO类中。

4 开发生命周期

本文开发的CJW框架结构也明确定义了应用开发小组的人员角色及各自的作用:1)前端开发者主要负责设计开发JSP页面、Action/ActionForm类以及对外的Web服务接口;2)中间服务层的开发者则负责开发各种应用服务,并将这些服务相关的应用模块进行集成;3)底层开发者主要负责开发各种DAO类以及密集型Web服务。各个角色之间的相互配合对整个应用开发的成败将起决定性的作用。

开发中经常会遇到的一个基本问题是当代码相关的组件不可用时如何对代码进行开发和集成。针对这个问题,CJW架构提供了一种以声明方式注入“模拟对象”的结构,这些“模拟对象”随着开发周期的推进将被实际的对象所取代。同时,编写、运行JUnit测试也使得测试工作成为开发过程不可缺少的一部分,CJW架构重点测试应用的服务以及服务之间的依赖关系。应用程序以EAR企业归档文件的形式进行部署,EAR文件可以通过手工运行Ant脚本生成,也可以通过调度程序周期性的执行Ant脚本生成。建议在生成EAR文件之前完成所有的JUnit测试。

5 结论

本文提出了一个基于J2EE的web信息系统开发架构CJW,重点论述了开发J2EE项目应该考虑的系统架构、相关技术和开发步骤。该架构取自于真实的项目经验,目的是帮助开发者们以此为参考,更快、更好的构建J2EE系统并设计出满足自己需求的定制框架。不过,这只是冰山一角,只此一篇论文并不能描述清楚J2EE的技术细节以及J2EE在科学和企业应用中的潜在影响,尤其是在基于Web的非线性分析模拟软件方面,作者将进一步研究该CJW架构在此方面的应用和优化。

[1] 李成严,冯慧灵. 基于开源技术的Web应用架构研究[J].计算机技术与发展,2009,19(8): 27-30.

[2] 曾亮,齐欢,王小平等.基于J2EE核心模式的组合Web框架研究[J]. 华中科技大学学报(自然科学版),2007,35(6):43-46.

[3] 袁华强,王亚强,朱君. 利用J2EE轻量级框架构建Web应用研究[J]. 计算机工程与设计,2007,28(1): 22-25.

[4] The Spring Framework official website: http://www.springframework.org/.

[5] Martin Fowler discusses details of the dependency injection pattern and how spring injects dependen cies: http://www.martinfowler.com/.

[6] JUnit framework: http://www.junit.org/.

[7] A.S. Boranbayev,Optimal methods for java web services,News of the National Academy of Science of the Republic of Kazakhstan 5 (2007) 38-43.

猜你喜欢

单元测试配置文件数据源
从Windows 10中删除所有网络配置文件
用软件处理Windows沙盒配置文件
互不干涉混用Chromium Edge
利用属性集相关性与源误差的多真值发现方法研究
基于Zookeeper的配置管理中心设计与实现
Web 大数据系统数据源选择*
基于真值发现的冲突数据源质量评价算法
一年级上册第五单元测试
一年级上册一、二单元测试
装备保障数据集成平台