Arch4样本程序简易开发指南.doc_第1页
Arch4样本程序简易开发指南.doc_第2页
Arch4样本程序简易开发指南.doc_第3页
Arch4样本程序简易开发指南.doc_第4页
Arch4样本程序简易开发指南.doc_第5页
已阅读5页,还剩37页未读 继续免费阅读

下载本文档

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

文档简介

Arch4样本程序简易开发指南2009年5月目录Arch4样本程序简易开发指南11页面开发21.1JSP规范开发31.2JS规范开发31.3YUI规范开发31.4标签规范开发61.5CSS的规范开发82Action开发82.1Struts配置规范开发92.2Action类必要数据组装规范开发102.3服务调用规范开发122.4Log规范开发132.5异常规范开发143业务服务开发143.1接口规范开发143.2服务调用规范开发143.3Log规范使用143.4异常规范使用153.5缓存规范使用153.6基类继承规范164组件服务使用164.1异常的规范使用164.2Log的规范使用174.3规则引擎的规范使用194.4Quartz定时服务的规范使用204.5缓存的使用规范204.6Arch4类库的规范使用214.7单元测试的规范使用214.8DWR的规范使用214.9WebService的规范使用214.10JMS的规范使用254.11Hibernate Tools的规范使用254.12P6spy的规范使用255BPM工作流的开发265.1背景介绍265.2开发过程详解29项目组成员是否必读要求程度项目经理是 否了解文档结构 明白文档内容 透彻理解系统分析师(业务)是 否了解文档结构 明白文档内容 透彻理解系统分析师(技术)是 否了解文档结构 明白文档内容 透彻理解高级程序员是 否了解文档结构 明白文档内容 透彻理解开发工程师是 否了解文档结构 明白文档内容 透彻理解质量保证工程师是 否了解文档结构 明白文档内容 透彻理解修订历史修订章节类型日期作者说明全部创建2009-05-31张大维ARCH4样本程序简易开发指南。第5章创建2009-5-31王智工作流开发知道第4章创建2009-5-31张凡组件服务的使用1 页面开发页面是客户首先能看到的表象,页面是否友好在很大程度上能影响使用者对当前系统的评价。所以好的页面开发业包含很多的规范,包括jsp,js的也发,标签的使用,css的使用等等。1.1 JSP规范开发严格按照开发规范执行,具体详见Arch4样本程序开发规范。 文件头需要导入,确保引入必要文件 需要,等等html标准标签 文件头需要导入Css文件 JS文件的导入需要在标签后引入 使用标准Html标签结合EL表达式进行页面开发1.2 JS规范开发严格按照开发规范执行,具体详见Arch4样本程序开发规范。 建议独立建立JS文件,js全部写在这个文件中以便统一管控 每个方法都需要增加方法的注释 尽量增加注释1.3 YUI规范开发1.3.1 查询结果集 增加executeQuery方法,并参照样本程序进行修改。 var myColumnSet = new YAHOO.widget.ColumnSet(contentColumnHeaders);需要在页面加载的init中初始化contentColumnHeaders初始化如下:contentColumnHeaders =key:userCode,text:人员工号,width:40em,sortable:true,type:link,key:userName,text:人员名称,width:40em,sortable:true,key:prpDCode,text:机构代码,width:40em,sortable:true,key:newUserCode,text:最新员工代码,width:30em,sortable:true,key:edit,text:修改,width:30em,sortable:true,type:link,key:delete,text:删除,width:30em,sortable:true,type:link; 初始contentColumnHeaders时候,其中的type:”link”是说明这列数据在初始加载的时候可以去执行方法,同样需要在init中加入,具体方法如下:YAHOO.widget.Column.formatLink = function(elCell, oRecord, oColumn, oData) if(oColumn.key=createTime | oColumn.key=updateTime) var date = new Date(oData.time); elCell.innerHTML = date.toLocaleString(); else if(oColumn.key=edit) elCell.innerHTML=修改; else if(oColumn.key=delete) elCell.innerHTML=删除; else if(oColumn.key=userCode) elCell.innerHTML=+oData+; else elCell.innerHTML = oData; ; var myDataSource = new YAHOO.util.DataSource($ctx/user/query.do);修改其中的URL,修改为需要请求的具体链接即可。 myDataSource.responseSchema 中的fields部分。按照上面的contentColumnHeaders填写这部分 myDataSource.subscribe(responseParseEvent,SINOSOFT.util.navigation);此处指定查询结果的导航栏,同样也可以自己制定 myDataSource.connMgr.setForm(fm);此处的fm为当前Form的name,如果命名不正确的话会对页面跳转的传值有影响 contentDataTable = new YAHOO.widget.DataTable(content,myColumnSet,myDataSource,myConfiges);此处的content为html中定义的一个div的id,为显示结果的区域。按照需要修改以上关键点后即可完成一个YUI组件的Ajax的数据查询。1.3.2 Autocomplete组件使用YUI 的Autocomplete取代老框架的双击域和下拉框.此技术是在YUI的Autocomplete基础上进行了封装并结合DWR技术进行整合。形成了我们现在使用的Autocomplete效果。 InputLoad 实现动态数据查询效果ComCode inputLoad1请选择机构代码input type=text class=selectui-input value= name=comCode /注意:a) 这段代码对格式要求很严格,注意格式,进行格式化后可能失效。b) Type必须是inputLoad,否则不能实现动态查询效果c) inputHint 查询前现实的提示文d) 代码最后的div的id名称必须为第一个type=”text” input的name增加”_Container”e) Type为text的input为页面展现使用f) Type为hidden的input为数据传输使用 StaticSelect 实现下拉框的静态初始 StaticSelect $riskCode firstLoad1 查勘类型代码或名称 注意:a) CodeType必须为StaticSelect否则不能实现下拉框数据的静态初始b) 仿照上面例子编写即可。1.4 标签规范开发1.4.1 JSTL标签此处我们已经引入了标准的JSTL标签,大家在页面开发的时候可以直接引用即可,无需关心如何整合的。 c:set在页面范围内定义state变量,以$state进行赋值 c:if用于分支半段,完成test中的EL表达式即可 c:when可以理解为if else中的if,需要结合c:choose中使用 c:otherwise相当于可以理解为if else中的else。需要结合c:choose和c:when使用 c:choosec:when和c:otherwise的外层必要嵌套 c:forEachItems的值为页面中可以获取的数据或者序列对象,var中定义了在标签中使用的当前叠代记录的变量名。Jstl标签库是非常强大和完备的,此处只是指出了我们可能会常用到的几个,如果在开发中用到了其他标签,可以查询相关的资料。1.4.2 自定义标签为了使页面开发更加的简便,同时也是为了满足更多的业务需求和个性定制,我们也自己定义了多个标签实现。具体tld如下:大家可以参看/WEB-INF/tlds/ce.tld文件了解具体的详情 ce:select下拉框显示方式,其中list参数可以是想上例现实的自定义的选项,当然也是可以指定成一个list变量进行显示。主要用于list数据的下拉框显示 ce:codetag代码翻译标签,通过codeType,对codeCode进行代码翻译 ce:codeselect通过codeType进行查询,查出的数据作为list进行下拉框显示。主要针对基础数据进行select展示。 ce:checkboxlistCheck box的展现形式 ce:radioRadio的展现方式1.5 CSS的规范开发使用工程定义好的CSS,不允许自己定义。具体css可以参看cssShow.jsp页面2 Action开发Aciton层面是处在页面和服务之间的一个层次,主要的功能是负责数据的组装和传输。请不要在Action层中完成业务逻辑,只能有具体的数据组装的逻辑。请明确Action层的具体作用和职责。2.1 Struts配置规范开发Struts2相对struts1有了比较大的改变,此处我们不谈他的实现原理,我们只是从开发角度去了解如何使用struts和如何配置struts.2.1.1 页面使用我们要有页面的请求的格式$ctx/user/update.do $ctx为发布的名称,可以自动获取,在这里这样写就可以 /user为struts的包名,用包来对一系列的方法请求进行管理 /update.do 为具体的请求,此样本程序我们以.do为请求的结束符,此处的update是配置文件里面的方法名2.1.2 配置文件首先struts2会在工程发布初始加载classpath中struts.xml文件。此文件中包含了很多struts的配置。同时struts也会去检索此配置文件的请求配置,不过对于一个大型系统来说这个配置文件会非常的大,所以我们的把每一个包的请求放到一个单独的文件中进行独立管理。这种做法我们只是需要在struts.xml中导入新的配置文件即可。具体如下:然后我们的工作就是在struts-user.xml中去进行配置即可./pages/platform/user/UserQuery.jspPackage标签描述了一个struts中的独立单位-包,name为user, namespace为/user也就是说,我们在页面使用请求的时候要使用/user的话,请求就会读取此配置文件进行相关的匹配。具体的请求是以action为执行处理单位。 name:页面请求的.do全面的具体名称,例如:update.do.在这里对应的就是name为update的action。 class:为具体的执行方法类。两种写法:可以写完整的类名(包括包名),当然也可以通过从spring的配置中读取,直接写bean id。 method:是指的在实际类中的方法名。从此可见,页面的请求名可以和实际类中的方法名不一致,不过我们为了便于管理要求请求名和方法名必须一致。 result:指定了方法执行完后的页面跳转目标。其中的name属性是指具体类方法的返回值(注意:input是错误的返回默认值)2.2 Action类必要数据组装规范开发首先作为struts的一部分,我们自定义的的Action类需要继承我们已经封装好的Struts2Action类,继承后我们就可以专心去编写数据组装的逻辑而不用在意页面跳转和一些数据组装的实现了。2.2.1 数据准备/* 操作类型 */private String opreateType;public String getOpreateType() return opreateType;public void setOpreateType(String opreateType) this.opreateType = opreateType;opreateType为页面需要使用的一个变量,我们只需要在action中定义此变量,并生成get和set方法,剩下的工作就交给struts的值堆栈来完成数据的获取和插入。然后这个变量不管是在action中还是在页面中,都可以直接使用,无需过多的工作。2.2.2 常规开发/* * 准备更新员工信息 * * return */public String prepareUpdate() logger.debug(准备更新 + userCode + 员工信息);opreateType = edit;prpDuser = userService.getUser(userCode);return SUCCESS;此处要做的就是组装数据,然后调用业务服务,获取返回值然后返回到页面进行展示。2.2.3 writeJSONData使用此方法主要用于YUI的结果集查询。if (pageNo = 0) pageNo = 1;if (pageSize = 0) pageSize = 20;QueryRule queryRule = QueryRule.getInstance();/ 获取QueryRule对象的Instanceif (prpDuser.getUserCode() != null& !.equals(prpDuser.getUserCode() queryRule.addEqual(userCode, prpDuser.getUserCode();/ 增加userCode的查询条件if (prpDuser.getUserName() != null& !.equals(prpDuser.getUserName() queryRule.addLike(userName, prpDuser.getUserName();/ 增加userName的查询条件if (prpDuser.getPrpDcompany().getComCode() != null& !.equals(prpDuser.getPrpDcompany().getComCode() queryRule.addLike(prpDCode, prpDuser.getPrpDcompany().getComCode();/ 增加comCode的查询条件if (prpDuser.getNewUserCode() != null& !.equals(prpDuser.getNewUserCode() queryRule.addEqual(newUserCode, prpDuser.getNewUserCode();/ 增加newUserCode的查询条件-try Page page = userService.findUser(queryRule, pageNo, pageSize);this.writeJSONData(page, userCode, userName,prpDCode, newUserCode); catch (Exception e) this.writeJSONMsg(e.getMessage();return NONE;分割线以上为查询条件的增加,而下面则为具体的writeJSONData实现。需要的只是直接调用基类的API即可.注意,此处的属性字段就是页面中yui 结果集展现的字段,务必一致,否则会出现问题。最需要注意的一点事,在此方法的return 时,需要方位NONE,表示不需要页面跳转。因为此处我们的结果集查询时使用了Ajax的特性,无需页面跳转,所以此处指定为NONE。2.3 服务调用规范开发首先在action中需要定义需要的服务,想上面提到的数据准备一直,建立服务对象,并给比get和set方法。/* 员工服务 */private UserService userService;public UserService getUserService() return userService;public void setUserService(UserService userService) this.userService = userService;准备完毕后既可以在需要的地方直接使用即可。/* * 更新员工信息 * * return */public String update() logger.debug(更新 + prpDuser.getUserCode() + 员工信息);userService.update(prpDuser);return SUCCESS;红字为服务的使用,就是这么简单。2.4 Log规范开发/* Log4j 必要配置 */private final Logger logger = Logger.getLogger(UserAction.class);Action初始的时候定义当前类的logger对象。在需要的时候增加logger使用/* * 新增员工信息 * * return */public String add() logger.debug(增加 + prpDuser.getUserCode() + 员工信息);userService.save(prpDuser);return SUCCESS;注意,在Action中的所有logger必须为debug级别。2.5 异常规范开发在action中可以直接throw出我们已经定义好的集中异常方式(其中最为常用的BusinessException),可以视具体逻辑而定。不过并不支持在开发中使用try catch 进行自定义的异常处理。不过有些时候不能避免,那就需要各位再异常处理的时候多加小心。出了异常不要仅仅catch住了就仅仅打印出了异常信息而程序还能继续执行,这样对系统来说可能是破坏性。3 业务服务开发业务服务才是我们行业系统的核心价值,也就是说,我们的业务处理逻辑全部在业务服务层进行开发和完善。所以说对次层级的规范就是对整个系统的规范。3.1 接口规范开发接口开发的诸多好处我在此处我就不说了,此处我们就是要求每一个服务实现类都需要对应一个接口类,而在action中调用的都是接口类。具体的接口和实现类的映射交给spring来做就可以了。同样实现类要实现接口类的方法。3.2 服务调用规范开发业务服务也可能需要其他服务的支持才能完成相关的业务操作,所以服务中调用其他服务也是很常见的。此处的服务调用与Action调用并无大异,大家可以参看2.3进行学习。3.3 Log规范使用参看2.4进行学习3.4 异常规范使用参看2.5进行学习3.5 缓存规范使用为了提高性能我们经常使用缓存来保存常用的数据以减少数据库相应的时间,从而提高整个系统的性能。所以我们会在服务中增加必要的缓存,下面我们就来看看具体的操作步骤。/* * 初始缓存实例 */private static CacheService cacheManager = CacheFactory.getIntance(CodeConstants.CACHE_TYPE, Company);通过缓存工厂使用Company名称创建一个静态的cacheManager,对与Company的cacheManager在整个工程是可见的,也就是说,如果其他的类同样使用了Company进行创建cacheManager的话,这些cacheManager是统一管理的,所以说清大家注意命名的唯一性。String key = cacheManager.generateCacheKey(listCodeSelect, codeType,riskCode, language, matches, pageNo, pageSize, typeParam,extraCond);Object result = cacheManager.getCache(key);if (Page) result != null) return (Page) result;Do something;cacheManager.putCache(key, page);return page;以上是具体的操作步骤: 通过关键字生成需要保存的key值,用于唯一一个缓存的值 通过key值或者当前的缓存对象,是否包含此值 如果有则使用缓存的具体值并返回 如果没有此缓存的话,则执行具体的方法,然后在执行完成后根据已经生成的key保存的缓存中以便以后使用。3.6 基类继承规范了解分层的同时可能发现一个问题,我们的框架里并没有我们常规意义上的DB层,仅仅存在UI,Biz层。这个DB其实在我们框架里是存在的,下面我们来说一下如何再现DB层。public class UserServiceSpringImpl extendsGenericDaoHibernate implements UserService 这个一个服务的头,其实UserServiceSpringImpl是此类的名称,UserService是需要实现的接口类,而GenericDaoHibernate就是我们的DB层了。我们封装后的GenericDaoHibernate继承了我们所会用到的所有的DB层操作,所以,我们在业务层的实现类中继承这个类后就可以在业务层中完全的操作DB了,这样就可以在一定程度上做到业务层和DB层的融合。GenericDaoHibernate PrpDuser是指当前服务的主要的服务对象,也就是说当前服务使用最频繁的对象,而String是指这个对象的主键值。通过泛型的定义可以使DB的使用更加的简单,当让这泛型也可以并不定义,不过使用的时候就需要制定需要操作的具体PO对象类了。4 组件服务使用作为一个通用的样本程序,不单单存在以上的业务开发环节就可以满足所有的开发和技术要求,这一章我们就会看到已经融合在我们样本程序中的很多技术的服务组件,可以给我们的样本程序带来很多活力和技术特点。4.1 异常的规范使用在上面的开发知道中我们也提到了异常的使用规范,原则就是可以直接throw业务异常,而尽量避免try catch处理逻辑,就算不能避免使用try catch的话,对出现的异常也需要精细化处理,不能只是简单的打印出一场堆栈,而程序还能继续执行,这样对系统来说可能是破坏性的。我想这些规范我们也是会严格遵守,对于我们定位和解决问题会带来很多的好处。现在很多的系统已经逐渐的挂在公网上了,在此我们不淡安全,不谈技术,只是说说这个异常。我们之前的异常处理已经做的非常的完备了,如果抛出异常的话,我们可以在页面上进行查看,并且能够查看非常完备和详细的异常堆栈信息,以便我们能很快的定位和解决问题。不过如果有一天我们的系统挂在公网上的话,一旦出现异常的话很多人都可以通过这个异常堆栈来了解我们的命名规范和处理机制,对于我们来说是很不安全的,所以在此样本程序中我们做了些许的改动,可以通过参数来配置,异常的模式,分为开发和生产模式,开发模式中存在异常堆栈信息,而生产模式的话已有异常信息而没有堆栈信息,不过想定位问题的话还是可以通过异常的log进行定位。Exception_Debug_Typetrue此配置存在于/resources/common/commonConfig.xml来完成配置,此处为true为开发模式,false为生产模式。4.2 Log的规范使用4.2.1 Log4j此样本程序使用的Log4j作为log的管理工具,上面已经提到了如何在程序中使用这个log,这里就不在赘述了,此处我们就说说如何配置即可。具体的log4j的相关资料可以参看log4j参考手册# UNCATEGORIZEDlog4j.rootCategory=ERROR, UNCATEGORIZEDlog4j.appender.UNCATEGORIZED=org.apache.log4j.RollingFileAppenderlog4j.appender.UNCATEGORIZED.MaxFileSize=10MBlog4j.appender.UNCATEGORIZED.MaxBackupIndex=5log4j.appender.UNCATEGORIZED.File=log/uncategorized.loglog4j.appender.UNCATEGORIZED.layout=org.apache.log4j.PatternLayoutlog4j.appender.UNCATEGORIZED.layout.ConversionPattern=%d %p %c - %n#userlog4j.category.ins.arch4platform.platform=DEBUG, PLATFORM log4j.additivity.ins.arch4platform.platform=falselog4j.appender.PLATFORM=org.apache.log4j.ConsoleAppenderlog4j.appender.PLATFORM.layout=org.apache.log4j.PatternLayoutlog4j.appender.PLATFORM.layout.ConversionPattern=%d %p %c - %n#mon.ExceptionMessageBean=ERROR, EXCEPTION mon.ExceptionMessageBean=falselog4j.appender.EXCEPTION=org.apache.log4j.RollingFileAppenderlog4j.appender.EXCEPTION.MaxFileSize=20MBlog4j.appender.EXCEPTION.MaxBackupIndex=5log4j.appender.EXCEPTION.File=log/exception.loglog4j.appender.EXCEPTION.layout=org.apache.log4j.PatternLayoutlog4j.appender.EXCEPTION.layout.ConversionPattern=%d %p %c - %n此配置文件分为3个部分,第一部分为基本部分可以记录下面几部分未能涉及到的范围,并进行管控。第二部分为ins.arch4platform.platform进行管控,实现的是在此包下面的log,debug级别以上的log都会打印在console上。第三部分是指mon.ExceptionMessageBean这个类中的error级别以上的log都会被写到log/exception.log文件中去,并20M为单位,5个文件轮询记录。4.2.2 AOP log通过AOP方式记录当前操作的方法和参数,并通过log4j进行配置输入目标。大家可以通过修改以上的配置,制定需要AOP涵盖的方法类,或者是包。不过此处不建议使用此方式记录,因为每次操作都记录的话会对系统性能造成非常大的影响。4.3 规则引擎的规范使用通过我们的封装,使用规则引擎就是像使用一个服务一样,引入,使用即可。/* *引入规则服务* */private RuleService ruleService;public RuleService getRuleService() return ruleService;public void setRuleService(RuleService ruleService) this.ruleService = ruleService;/* * 通过规则引擎更新NewUserCode * * param prpDuser * return */SuppressWarnings(unused)private PrpDuser updateNewUserCode(PrpDuser prpDuser) try prpDuser = (PrpDuser) ruleService.executeRules(user, prpDuser,/UserRuleApp/UserRule); catch (Exception e) return prpDuser;我们使用起来非常的方便,只要使用ruleService.executeRules即可完成对规则引擎的调用.”user”指的是在ilog端的别名,prpDuser就是我们需要入参的对象,所有的规则都是操作此对象,作为入参进入规则引擎,然后执行一系列规则后对此对象中的某一个字段进行修改,然后返回,就完成了一个规则的调用。对于我们程序开发来说,无异于一个服务方法的调用。/UserRuleApp/UserRule是指定的规则包名。具体的规则引擎使用还需参看具体的规则引擎开发指南。4.4 Quartz定时服务的规范使用Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个, 甚至是好几万个Jobs这样复杂的日程序表。Jobs可以做成标准的Java组件或 EJBs。Quartz的最新版本为Quartz 1.5.0。我们在Qua

温馨提示

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

评论

0/150

提交评论