Java项目开发平台开发规范.doc_第1页
Java项目开发平台开发规范.doc_第2页
Java项目开发平台开发规范.doc_第3页
Java项目开发平台开发规范.doc_第4页
Java项目开发平台开发规范.doc_第5页
已阅读5页,还剩48页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Java项目开发平台开发规范_北京东方国信电子有限公司CRM事业部时间:2003-8-27目 录Java项目开发平台开发规范1一、开发平台概述3二、技术综述51、Struts框架技术52、Hibernate数据持久化技术93、动态bean技术15三、在BONC-JONE平台上进行开发191、BONC-JONE平台目录说明192、如何使用BONC-JONE运行起来193、开发有关规范性要求及典型步骤19四、主要函数及使用技术方法说明43如何使用自定义标签库?43如何使用日志类写日志?45如何进行资源注册?48如何进行登陆权限验证?48如何进行字符转换?48如何对资源文件进行字符转换?48如何配置、读取应用配置信息?48如何打包boncpersistenceobj.jar文件?48数据操作方法的原理是怎样的?48如何将任意文件上传到数据库中,又如何下载?48如何保证在页面清空的字段能正确提交到数据库?48如何使用日期控件?49如何使用DBQuery类进行数据查询?49如何自动生成Hibernate持久化beans及map文件?49如何使用分页技术?51附录:54附A:Struts学习精要参考54附B:Hibernate学习精要参考54附C:技术备忘54一、开发平台概述BONCJONE开发平台是北京东方国信电子技术有限公司遵循“简单、有效、先进、可扩”的原则,通过整合Struts 1.1与Hibernate 2.1等优秀的开源技术设计并实现的一个J2EE开发平台。其架构图如下:这个体系架构的主体是MVC架构。MVC是Model/View/Control的缩写。Model/View/Control是软件设计的典型结构。在这种设计结构下,一个应用被分为三个部分:Model、View和Controller,每个部分负责不同的功能。Model是指对业务数据/信息的处理模块,包括对业务数据的存取、加工、综合等;View是指用户界面,也就是面向用户的数据表示;Controller则负责View和Model之间的流程控制,也就是完成两个方向的动作:1.将用户界面(View)的操作映射到具体的Model,以完成具体的业务逻辑;2. 将通过Model处理完的业务数据及时反应到用户界面(View)上。其系统组成结构图如下:平台辅助API表示层StrutsTiles业务层业务管理接口业务管理抽象类业务管理实现类业务Beans技术JDBC持久化层Hibernate连接池技术数据库DataBaseBONCJONE开发平台从总体结构上充分体现了分层的系统设计思想。分层的概念起源于操作系统及网络协议设计中,但目前这个概念已在所有面向对象的应用系统中相当流行了。BONCJONE开发平台主要层次分为:表示层、业务层、持久化层及一些各层公用的工具类库。分层的系统设计思想的重点在于:l 一个分层的系统在各相关层的实现代码间定义了接口,从而允许一个层的实现代码的变化不会影响到其它的层。l 分层系统结构还限制隔层依赖的发生,各层的通讯是由顶向下管理的。某一层仅依赖于直接位于它下面的那一层。每一层对其他层的存在都是不知道的,除非那一层紧邻其下。即使是对紧邻其下的层它也仅需要知道如何使用接口与其通讯就可以了,而无需知道其实现细节。BONCJONE开发平台通过Struts+Tiles技术实现了MVC模式中的表示层和控制层,通过Hibernate技术结合动态Bean技术融合成独特的业务Beans技术构建了数据层。二、技术综述1、Struts框架技术 Struts是一个基于J2EE的MVC框架。 J2EE体系包括JSP、Servlet、EJB、WEB SERVICE等多项技术。这些技术的出现给电子商务时代的WEB应用开发提供了一个非常有竞争力的选择。但怎样把这些技术组合起来,形成一个适应项目需要的稳定架构对项目开发是非常重要的。 设计一个框架,需要考虑的方面很多,不仅要对J2EE体系中的各种技术进行筛选取舍,并要考虑到开发过程中的角色分工、后期的运行维护,以及系统扩展性等诸多因素。 因此,一个成功的软件需要有一个成功的架构。MVC架构使得应用程序的结构更加清晰,通过将代码按照层次划分为业务逻辑/数据、用户界面和应用流程控制这三个层次,增强代码稳定性。我们知道,对于Model、View、Controller这三部分功能来讲,View的实现一般是由界面设计人员和界面程序员来完成,Model则是由业务逻辑程序员来完成,Controller则一般由负责整体控制的程序员来完成。Controller部分的代码比较稳定,一般会实现一个通用的架构;而Model则跟随商务流程的变化而变化;View的更改则是随着用户需求的更改而更改。这种模块功能的划分有利于在代码修改过程中进行模块的隔离,而不需要把具有不同功能的代码混杂在一起造成混乱。对于项目开发而言,有利于在项目小组内按照小组成员各自的擅长进行分工,有利于三个部分并行开发、加快项目进度。 当前可供选择的较为流行的MVC框架有六种之多:Struts、Maverick、WebWork、Turbine、RealMothods、AOP(aspect-oriented programming)。它们应用的领域及实现的侧重点各有不同。但以Struts应用最广,是基于MVC模式的Web应用最经典框架,当推首选。 Struts最早是作为Apache Jakarta项目的组成部分问世。项目的创立者希望通过对该项目的研究,改进和提高Java Server Pages (JSPs)、Servlet、标签库以及面向对象的技术水准。 Struts这个名字来源于在建筑和旧式飞机中使用的支持金属架。它的目的是为了帮助我们减少在运用MVC设计模型来开发Web应用的时间。 因此我们选择Struts。Struts鼓励按照Model 2方式构建应用的体系。Model 2是MVC基本设计模式的一种变体。MVC设计模式的优点是,它使得Model、View和Controller各个部分之间相对独立。Struts在一个中心位置装配ActionServlet、ActionMapping和各种Action类,处理所有传入的HttpServletRequest。ActionServlet把各个传入的HttpServletRequest分发给Action类,而ActionMapping对象可通过Struts-config.xml配置文件控制,它告诉ActionServlet如何分发请求。 本图示意了Struts各个部分之间的通信过程Controller的功能:在客户端、View和Model之间起协调、仲裁的作用。只有Controller才会与Model和View联系,在这中间它就象是一个交换机,而Model和View之间不会直接通信,这样,Model、View和Controller就被分隔开来。这是成功运用Struts的关键所在。说明一下:所有Controller的逻辑应当放入Action类,与应用的其他层的通信可以在这里进行。虽然我们可以把业务逻辑也放入Controller,但一般而言最好不要这么做。应当改用Model部分的组件,因为这些组件才是真正处理数据的地方。把数据保存到数据库也应当是Model的功能之一。当Controller处理好一个HttpServletRequest,它把请求转发给View。View的唯一任务是表现数据,在Struts中,View一般使用JSP技术。在Struts中,Controller和View之间的所有通信都通过HttpServletRequest、HttpSession和ServletContext间接完成,对于这些操作来说,首选的技术莫过于Servlet,Struts直接把HttpServletRequest传递给Servlet或者是JSP,不过Servlet容器会自动把JSP转换成Servlet。Struts框架将其侧重点放在了Controller与View层。View由JSP定制标记库和JSP页面共同构造,其中ActionForm类是一种类似JavaBean的ValueObject对象,带有set和get方法,用来保存客户的状态。按照Struts的MVC概念,ActionForm位于View和Controller之间的中间地带。Struts提供了一组完备的专用标记,用来从JSP访问ActionForm里面的数据。Controller由ActionServlet、ActionMapping和各种Action类相互配合来完成。其中Action类给开发人员自由发挥的空间比较大,因此,在开发过程中完整地遵从MVC的概念Action类的使用方式是一个关键。对于Struts的解剖。图解说明:其中不同颜色代表MVC的不同部分:红色(控制器)、紫色(模型)和绿色(视图)l 首先,控制器(ActionServlet)进行初始化工作,读取配置文件(struts-config.xml),为不同的Struts模块初始化相应的ModuleConfig对象。比如配置文件中的Action映射定义都保存在ActionConfig集合中。相应地有ControlConfig集合、FormBeanConfig集合、ForwardConfig集合和MessageResourcesConfig集合等。l 控制器接收HTTP请求,并从ActionConfig中找出对应于该请求的Action子类,如果没有对应的Action,控制器直接将请求转发给JSP或者静态页面。否则控制器将请求分发至具体Action类进行处理。l 在控制器调用具体Action的execute方法之前,ActionForm对象将利用HTTP请求中的参数来填充自己(可选步骤,需要在配置文件中指定)。具体的ActionForm对象应该是ActionForm的子类对象,它其实就是一个JavaBean。此外,还可以在ActionForm类中调用validate方法来检查请求参数的合法性,并且可以返回一个包含所有错误信息的ActionErrors对象。如果执行成功,ActionForm自动将这些参数信息以JavaBean(一般称之为form bean)的方式保存在Servlet Context中,这样它们就可以被其它Action对象或者JSP调用。Struts将这些ActionForm的配置信息都放在FormBeanConfig集合中,通过它们Struts能够知道针对某个客户请求是否需要创建相应的ActionForm实例。l Action很简单,一般只包含一个execute方法,它负责执行相应的业务逻辑,如果需要,它也进行相应的数据检查。执行完成之后,返回一个ActionForward对象,控制器通过该ActionForward对象来进行转发工作。我们主张将获取数据和执行业务逻辑的功能放到具体的JavaBean当中,而Action只负责完成与控制有关的功能。遵循该原则,所以在上图中将Action对象归为控制器部分。本图给出了客户端从发出请求到获得响应整个过程的图解说明。以上我们从原理上剖析了Struts,关于具体如何应用Struts框架框,请参看附录A。2、Hibernate数据持久化技术 Hibernate 是一种object/relational mapping (ORM)的持久化技术。 曾经,包括现在也有许多J2EE项目在直接使用SQL/JDBC实现持久化。众所周知的DAO模式让我们把复杂的JDBC编码和大量SQL隐藏到业务逻辑和领域模型之后,但这种方式实现的是有限的分离,最致命的是应用由一种数据库向另一种数据库迁移时可移植性非常差。另外它要求开发者对项目中使用的关系数据库管理系统非常熟悉,而且要精通SQL。 当前可供选择的较为流行的数据持久化技术也同样有很多:EJB、Hibernate、JDO、OJB、Cayenne、SimpleORM、JAXOR等等。 不选用EJB的理由 EJB在J2EE应用里是一个重量级的组件,它由容器提供了分布、事务等多种企业级应用需要的特性。我们不选用它主要是因为:l 兼容性问题。规范一模一样,实现各有不同,当从某一种EJB容器向另一种EJB容器移植时维护的成本会很高。l 性能问题。l 不支持动态Query的问题。Entity Bean最终的执行代码是在部署编译时生成的,很难实现动态Query。l 如果一个应用对事务处理要求很高,访问量非常大需要实现分布式集群时EJB才是必须的。选用Hibernate的理由 Hibernate是当前最活跃,应用最广,更新最快,文档最完整,功能最齐备的一个数据持久化的开源项目。选用它的理由主要有:l Hibernate并不直接反映数据库中的表和列,它通过一些持久化类(JavaBeans)来映射到数据库中的表上。这些持久化类与我们通常使用的JavaBeans没有任何不同,它们即可以由Hibernate来持久化,同样重要的是它们也可以完全与Hibernate无关地被使用。这是它与其它持久化模型(比如EJB)的一个重要的区别即Hibernate的持久化类是纯JavaBeans,它可以在任何地方被使用,而不需要容器。l Hibernate提供了一种对象导向的查询语言(HQL)。几乎支持所有的SQL语法,传统数据库可以做的它就可以做。l Hibernate提供了数据分段提取控制功能。l 将Hibernate放在SLSB后,它同样可以实现分布式应用,同样可以利用容器提供的JAT事务服务。因此我们选择Hibernate。Hibernate概要结构图:Hibernate详细结构图:Hibernate使用概要l 手工创建或使用工具自动生成Hibernate的持久化类;文件示例:package eg;import java.util.Set;import java.util.Date;/* * hibernate.class * table=CATS */public class Cat private Long id; / identifier private Date birthdate; private Cat mate; private Set kittens private Color color; private char sex; private float weight; /* * hibernate.id * generator-class=native * column=CAT_ID */ public Long getId() return id; private void setId(Long id) this.id=id; /* * hibernate.many-to-one * column=MATE_ID */ public Cat getMate() return mate; void setMate(Cat mate) this.mate = mate; /* * perty * column=BIRTH_DATE */ public Date getBirthdate() return birthdate; void setBirthdate(Date date) birthdate = date; /* * perty * column=WEIGHT */ public float getWeight() return weight; void setWeight(float weight) this.weight = weight; /* * perty * column=COLOR * not-null=true */ public Color getColor() return color; void setColor(Color color) this.color = color; /* * hibernate.set * lazy=true * order-by=BIRTH_DATE * hibernate.collection-key * column=PARENT_ID * hibernate.collection-one-to-many */ public Set getKittens() return kittens; void setKittens(Set kittens) this.kittens = kittens; / addKitten not needed by Hibernate public void addKitten(Cat kitten) kittens.add(kitten); /* * perty * column=SEX * not-null=true * update=false */ public char getSex() return sex; void setSex(char sex) this.sex=sex; l 手工创建或使用工具自动生成Hibernate的xml映射文件;文件示例: l 初始化ConfigurationConfiguration cfg = new Configuration() .addFile(Cat.hbm.xml) .addFile(DomesticCat.hbm.xml);或Configuration cfg = new Configuration().addClass(eg.Cat.class).addClass(eg. DomesticCat.class) l 获得SessionFactorySessionFactory sessions = cfg.buildSessionFactory();l 进行数据存取等操作Session sess = sessions.openSession(conn);/ start a new transaction (optional)Transaction tx = sess.beginTransaction();DomesticCat pk = new DomesticCat();pk.setColor(Color.TABBY);pk.setSex(F);pk.setName(PK);pk.setKittens( new HashSet() );pk.addKitten(fritz);sess.save( pk, new Long(1234) );sess.flush(); /force the SQL INSERTsess.refresh(cat); /re-read the state (after the trigger executes)mit();sess.close();l 使用HQL语言查询Query q = s.createQuery(from foo in class Foo where =:name and foo.size=:size);q.setProperties(fooBean); / fooBean has getName() and getSize()List foos = q.list(); 需要说明的是:Hibernate产生的所有SQL是运行时产生的,说的更准确一些是在你系统启动时产生。所有我们需要的只是一个包含映射元数据的xml映射文件。xml映射文件可以你手工来维护,也可以通过植入源代码的注释来产生。以上我们简要介绍了Hibernate的基本特点及使用方法,详细内容请参看附录B。3、动态bean技术 使用动态bean技术的理由:l 我们不只一次抱怨信息系统中数据项变化不定,无法设计和实现Java Beans。l 我们也不只一次作过这样的事情:数据项增加或减少了,我需要修改信息系统以求适应。比如我们按照某个企业的要求设计出了2000个Bean来满足该企业对信息系统中业务数据模型的需要,过了一定时间后,他们的业务发生了一定的变化,要对数据模型扩充一部分数据项,可想而知会有多么辛苦。动态beans技术就是为解决此类问题而生,它为解决由于数据项变化带来的设计和实现的变更提供了技术基础。动态bean技术主要概念:l 一个Bean属性的定义完全取决于有无访问者方法:设置器(setXXX())和获取器(getXXX()),而与在类定义中有无显示说明字段毫无关系。l 为了使Beans能确认一个属性,其设置器(setXXX())和获取器(getXXX())必须遵循下列命名规则: n 一个属性名在访问方法中必须以大写字母开头; n 在其它地方以小写字母开头。 l 扩展javaBean属性机制:定义了五种属性访问策略,使得属性的访问代码像脚本一样在运行时决定,另外一个进步就是它支持List和Map属性的元素属性,也就是扩展javaBean属性机制它不把一个Bean的某个List和Map成员看成一个整体属性,而是动态地把这个List和Map成员的元素看成属性,这样无疑提供了一种无限扩展Bean属性的能力。Common-beanutils 1.6中的propertyUtils实用类使用Java语言的内省反射功能实现扩展属性的设置器和获取器。propertyUtils定义了引用一个特定Java bean属性的五种格式:n 简单属性,格式beanNpNpName标识了JavaBean beanName的一个属性,这个属性的获取器和设置器的方法是通过JavaBean的标准内省功能决定的。如果要改变简单属性的值,必须要有设置器操作,可以想象成类似调用beanName.getpropName()|setpropName(value); n 嵌套属性,格式beanNpNpNpName3。像简单属性一样,第一个propName1元素被用来选择一个属性获取器方法,在这个方法返回的对象上使用propName2的获取器方法返回下一个对象,最后这个对象的属性propName3被访问或设置,可以想象成类似调用beanName.getpropName1().getpropName2().getpropName3()|setpropName3(value); n 索引属性,格式beanNpNameindex。属性propName1可以是一个数组, java.util.List或者JavaBean beanName有索引属性获取器和设置器操作。bean只需propName的获取器方法,可以想象成类似调用beanName. getpropName (index)|setpropName(index,value); n 映射属性,格式beanName. propName(key)。propName是一个java.util.Map实现。bean只需propName的获取器方法,可以想象成类似调用beanName. getpropName ().get(key)|set(key,value); n 组合属性,格式beanName. propNpNpName3(key)。 l 动态bean:动态bean具有动态属性,也就是说可以由程序运行时构造bean的属性,而不是像标准的javaBean在编译时决定一个bean的属性。定义和访问一个动态bean的步骤如下:n 定义一个动态属性Dynaproperty数组,动态属性Dynaproperty定义了一个属性的名字和对象类型; n 用定义好的动态属性数组实例化一个动态类; n 由动态类返回一个动态bean; n 可以用propertyUtils访问和设置动态bean的属性。 下面是定义和访问动态bean的代码:/ TestDynaBean.javaimport mons.beanutils.*;import java.util.*;public class TestDynaBean public static void main(String args) TestBean bean = new TestBean();Object value = null;try Dynaproperty px = new Dynaproperty(subordinate, bean.getClass(), new Dynaproperty(firstName, Class.forName(java.lang.String), new Dynaproperty(lastName, Class.forName(java.lang.String); DynaClass dynaClass = new BasicDynaClass(employee,null, px ); DynaBean employee = dynaClass.newInstance(); propertyUtils.setproperty(employee,subordinate, bean); propertyUtils.setproperty(employee,subordinate.listIndexed0,dy bean set); propertyUtils.setproperty(employee,firstName, Fred); propertyUtils.setproperty(employee,lastName, Flintstone); System.out.println(subordinate.listIndexed0:); System.out.println(propertyUtils.getproperty(employee,subordinate.listIndexed0); System.out.println(firstName: + propertyUtils.getproperty(employee, firstName); System.out.println(lastName: + propertyUtils.getproperty(employee, lastName);catch (Exception e )System.out.println(e.toString(); 从配置文件配置动态bean的动态属性好处在于既能固定又能更改动态Bean的属性,这些属性是这个动态Bean对外界的宣布的访问协议。动态属性Dynaproperty的主要构造函数接受两个参数:第一个为属性名称,为字符串性,第二个为属性的类型,为Class类型。从配置文件读取的资料普通为字符串型,我们可以用ClassLoader把配置文件中字符串型的属性类型转化成Class类型的属性类型。下面struts 1.1 中struts-example.war的 formbeans.xml中的片断体现了如何在配置文件中定一个动态bean的动态属性:下面RequestUtils的代码片断体现了如何从字符串表示的属性类型转化成Class型的属性类型:public static Class applicationClass(String className) throws ClassNotFoundException / Look up the class loader to be used ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); if (classLoader = null) classLoader = RequestUtils.class.getClassLoader(); / Attempt to load the specified class return (classLoader.loadClass(className); 这就是关于动态bean的所有奥秘,RequestUtils类代码片断public static ActionForm createActionForm就是这样创建动态bean的。三、在BONC-JONE平台上进行开发1、BONC-JONE平台目录说明注意:mon、com.bonc.security包属于开发平台基本支持包,其中的文件不允许开发人员改动。2、如何使用BONC-JONE运行起来 将开发平台从source safe拉下来后,只需要将src目录下的bonc_perties文件中boncHome=的路径改为你所下载目录的实际路径,如:boncHome=D:DevelopWorkjavaboncCrmexamplerootWEB-INF,做了这样的设置后,系统启动时就会到这个目录下去找我们的项目配置文件bonc_config.xml。 如果你使用的是Jbuilder,还应该将lib目录下的所有包文件,加入到你工程的Required Libraries中。 做完以上工作bonc-jone应该就可以正常运行了。3、开发有关规范性要求及典型步骤l 应用的包的组织规则n 客户关系项目中所有与应用模块相关的包均应在com.bonc.crm包下,如果开发的是其他项目则根据项目名称来定义这个包名称,可能是这样的:com.bonc.sample等。n 在com.bonc.crm包之下,以模块名称来分包,比如:模块名称是“留言模块”,就要定义一个与其对应的包com.bonc.crm.module.leaveword。n 在各模块包下再分为bean包(存放Form bean及其他本模块可能要用到的 bean)action包(存放Action类)与bussinessmanager业务管理包(存放业务管理接口类),比如:com.bonc.crm. module.leaveword.action、com.bonc.crm. module.leaveword.bean与com.bonc.crm. module.leaveword.bussinessmanager包。n 在各模块的业务管理包下再定义业务管理实现类包(impl包存放业务管理接口的实现类),比如:com.bonc.crm. module.leaveword.bussinessmanager.impl。n 包定义的要求:全部小写字母定义。l 应用开发中主要编写的类的作用n Form bean类:建议开发中尽量使用动态Form bean(即根据struts的配置文件生成的动态bean),特殊情况下才写Form bean类。该类是一个ValueObject对象,主要的作用是包装客户端请求,将数据从view层传给Action类,由Action类转给业务处理类进行处理;或者由Action类更改或填充其中的数据,然后将其传给view层来显示。n Action类:Action类主要完成三方面的功能,其一是做登陆及权限验证,其二是做数据校验,其三(也是最主要的)负责完成与控制有关的功能。需要注意的是尽可能不要此类中包含业务处理功能。n 业务管理接口类:该类是对业务对象进行操作的抽象,是一个接口,对该业务对象的操作均应通过它来进行。n 业务管理抽象类:这种类实现或部分实现业务管理接口中定义的方法,业务操作的大部分代码均应该写在这个类中。由于这个类是个抽象类,所以它不能够被实例化。n 业务管理实现类:这种类是业务管理抽象类的继承类,通常情况下其中无实际代码。l 应用开发中关键的配置文件的意义及功能n web.xml文件:是Web应用最基本的部署描述配置文件。部署Web应用首先要配置web.xml文件。开发人员需要在Web.xml部署描述文件中配置:有效的部署描述文件必须包含DTD声明:web-app标记是部署描述文件的根元素,它的子元素包括:元素描述icon此元素指定在GUI工具中表示此Web应用的大图标和小图标,包含一个small-icon和一个large-icon元素,可使用GIF或JPEG格式的图像display-name此元素提供在GUI工具中此模块的短名字description此元素提供关于父元素的描述性文本distributable如果在Web应用部署描述中使用该元素,就表示该Web应用可以部署到分布式Servlet容器context-param此元素包含Web应用的Servlet环境的初始参数servlet包含一个servlet的声明性数据servlet-mapping在servl

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论