`
CaptainCook
  • 浏览: 136955 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Webwork及框架设计

    博客分类:
  • J2EE
阅读更多

Webwork及框架设计

    现在这个项目已经做了半年多了,我也是从需求调研时开始加入的,现在正是设计完成后的紧张编码阶段。具体的编码工作我已经做了整整两周。我主要是开发后台,也就是权限管理相关部分。部分后台我们是用webworkSpringHibernate,一种很流行的J2EE开发模式,我现在主要是归纳总结一下。

 

(一)   表示层(Presentational LayerWebwork总结

作为一个表示层框架,无论是StrutsWebwork,还是SpringMVCJSF,它们都是解决同一类问题。

表示层框架,从分层的角度考虑,它的核心是作为一个Front Controller,在Struts里面是ActionSerlvetRequestProcessorAction,前两个是框架本身的,只有Action需要我们处理。它的职责也就是协调用户的输入,将请求dispatch给后端business,由后端business系统处理后,将相应的结果返回给Controller,再由Controller处理返回给用户。

对于开发来说,特别需要注意的是职责分配的问题,这是我们开发过程中最容易犯的毛病,也是最需要注意的地方。Front Controller只是一个Controller,也就是Call别的接口,自己本身不应该有处理业务的职责,它应该尽量的thin。如果不遵守这个原则呢?那带来的将是系统难以测试,难以重用,难以维护。

具体来说,我们的业务系统是可以重用的,可以提供Service接口给Web层调用,也可以提供给其它系统通过Web Services接口调用,还可以给分布式client调用。它们的调用方式,一般有三种:

最普通的调用。在web系统中,就是表示层Controller直接调用服务层。

依赖注入式调用(Dependency Injection)。它需要IoC容器支持,如SpringpicoContainer,它对解耦和测试非常有用

依赖查找式调用(Dependency Lookup)。也就是EJB里面的JNDI,它最大的好处是支持分布式开发和组件开发。

我们一定要牢牢记住表示层的职责。表示层框架很容易变,但系统业务还是相对固定,如果你接触过物流系统,你就会明白什么叫业务了,那时候在表示层里处理业务会非常可怕,因为我的业务要同时支持几种客户端:桌面clientBrower、移动client,难道你需要在每种client里面写业务吗?而且,表示层框架的开发人员可以不需要懂太多的业务就可以利用自己的技术优势,来调用业务相关接口。

 

下面我再具体谈谈表示层需要处理的几个部分:

整体说明

举个例子,我现在想对updateUser.do?userId=19做出请求,然后在一个UpdateUserAction里处理用户预更新,然后将结果导向到updateUser.jsp页面。这大概是我们所希望的最简单的处理方式吧。

上面那三个元素的相互关系在web框架的配置文件里面定义。现在的framework都倾向于configmetadata oriented,因为这样的框架会比较灵活、好维护,试试直接用JSPSerlvet开发你就知道要做多少重复工作和hard code了。

webwork里面,是xwork..xml,在Struts里面,是struts-config.xml,在JSF里面,是faces-config.xml。所以说,框架都是相通的。我这里需要特别指出的是,上面那些文件和文件名都是默认的,实际上,为了支持组件开发和团队协作开发,保持开发模块之间的松耦合,我们应该将配置文件分解成一个个的segment

对于action,也就是前面提到的Front Controller Struts里面,是通过继承基类的Action,在webwork,是通过实现Action接口。

Struts里面,通过继承方式来实现Action,那么我们代码是和框架紧密耦合的。而且,只支持JSP,不支持模板语言,如VelocityFreeMaker,而这些可以脱离Servlet容器,最大的好处是,我们的网页设计人员可以专心做html界面。分工就意味着效率和质量。但Struts这种框架就支持不够。

webwork就很好地做到了这种解耦,action和前端表示完全分离,如表示页面还可以直接发布成pdf文档。

那么,继承基类和实现接口,对于我们开发人员意味着什么呢?灵活性、容易测试,这让我开发更容易一些。

Scenario 1  我们一些简单的CRUD操作,完全可以在一个action里面处理。虽然Struts也可以这样,因为它有一个DispatchAction,但你会发现,项目中,我们经常引入一个BaseAction,而这个BaseAction是继承DispatchAction还是Action,往往很难决择,因为我们这两种需要都有,虽然DispathAction也是继承Action。而webwork的处理就方便多了,你需要验证、国际化、安全等等很多操作,你都可以通过实现一个接口实现。

Scenario 2 我们测试Action的时候,总是要启动容器,启动一般要花将近半分钟,这会让我们很多时间都花在等待之中,由于Action和容器脱离,我们的测试会更迅速和直接。

 

我现在就按照整个页面流程来分类说明,在一个web框架下开发,或是开发web应用,或者开发Web Framework必须考虑到的各个方面:

1.       表单提取

我们开发web MIS系统,从技术角度考虑,第一步就是在页面输入数据,然后将它们保存到后端数据库。

框架应该自动提取表单数据,将这些String类型的数据转换成对应的数据类型,并封装为值对象(Value Object),提供给Controller,作为Controller的输入。

Struts是通过ActionForm,非常笨拙,而且对类型转换都支持不够。Webwork在这方面做得优雅多了,它将请求参数封装为一个Map对象。其实,请求本来就是key-value对。然后当数据传入到action后,就和Serlvet容器,web脱离了关系,这带来的解耦的好处就是还可以支持多种客户端,支持容器外测试。

具体实现上,Struts通过BeanUtil工具对ActionForm进行反射;webwork是通过一个拦截器Parameters Interceptor来获取,而action实现该接口,然后在配置文件里申明一下就ok了。

2.       表单验证

我们输入数据,一般需要符合一定的规范,如必须输入数字,不能为空,必须为邮政编码等等。

解决这个问题,如果不用framework,我们需要在jsp页面上用javascript验证,还要在servlet里面获取参数,然后验证,对于不合理的数据,需要将之保存,并附上错误说明,然后forword到原来jsp页面显示处理,非常烦琐和机械。

Struts框架原来处理还是挺机械的,主要在ActionFormvalidate方法里验证,后来加入一个Validation框架,也就是一个plug-in,非常好用。Webwork也沿用了这一点,两者在验证上都不错。

但我们必须注意的一个问题,那就是验证不通过时,怎么保持原来的数据,特别是下拉框里面的数据,Struts处理很麻烦(难道我没用好?),webwork好用多了,不过有个tips,那就是将select的下拉列表保存在session里,不用每次验证不通过都重新从数据库加载。

另外还有一点,那就是和表单重复提交结合时会出现的问题,struts中,处理不当,就会出现在你验证不通过,修改后再次提交时总是被提示重复提交。 Webwork是通过一个Interceptor截获,处理很自然。不过我建议时提交通过后,用redirect,这样就不存在重复提交的缺陷。你总不希望因为网络慢,你的订单由于刷新而提交两遍,收到两份相通的货物吧。

3.       国际化和resource文件

Web界面是给用户看的。譬如,我们公司内网打算采用一套很知名的blog系统,但它是德国人开发的,但是你总不会希望看到界面是德文吧。这套blog开发商为了全球推广,也不至于为每种语言都开发一套吧,那不累死,维护简直就是恶梦。

我之所以现在要提到国际化,不光是国际化的问题,因为在表单验证时,如果field不通过,都会提示用户,但这些提示语一般都会重用,如createupdate用户时“用户名不能为空!”,我们可以在resource文件里定义一个keyerror.user.username.required,然后在各处引用。

WebworkStruts对这个都处理比较好,这也是一个表示层框架必须处理的。我建议不要在Action-validation.xml文件里hard code这些信息,而是将它们分离出来。

4.       请求路由

当我们将user成功提交后,我们让它由谁来处理呢?这就是请求路由的问题。

这种关系在配置文件里面定义,我上文都提到过。为了方便,往往将多个请求提交到一个action的不同方法,这是我们应该好好利用的。而它们在webwork里面都可以很好配置。例如,将saveCreatedUser 路由到UserActionsaveCreatedUser方法里。

5.       请求处理

当请求发生,并且路由到正确的action后,我们的action就要处理它了,包括初始化,处理,清场。

关于Action需要注意的问题,我现在还要重申的是:一定要注意它的职责:不要处理它不应该处理的事情。

例如,注册用户时,用户姓名可以重复,但用户登录账号却不能重复。论坛发帖子就没有这样要求。再例如,会员系统中,用户积分达到100就是可以下载,但什么时候规则变了,需要积分150才能。这些规则在哪儿处理呢?最简单当然是在Action里:没有满足条件,就forward到输入页面。当规则很多时,你就很难维护了。反问一下,它是web层关心的问题吗?

在任何框架设计,包括web框架设计时,一般都有一个非常核心的模式,那就是template模式,它和一种称为callback的调用方式相关,也就是那个著名的好莱坞原则:don’t call me, I’ll call you! 具体到我们的web框架,也就是action,如webwork里面的ActionSupport,它们都是这种处理方式,我们不知道我们的Action是被谁调用的(当然是框架了),但我们这样写,然后在xml一配置,就work well

我们可以研究一下StrutsActionSerlvet,特别是ReqeustProcessor,后者就是一个典型的template模式,action是作为里面一个command运行的。Command模式也是用callback调用。关于这两种模式,google一下就清楚了。

Spring就是使用Templatecallback模式,对底层实现做了统一封装,其中template负责那些通用的功能,如事务、资源管理、异常处理,callback则完成变化的那部分,如处理具体的数据库statement操作。我们最常用的HibernateCallbackHibernateDaoSupport就体现了这一点,具体可参照其源码。

另外,对于Action,一定要注意线程安全的问题。Strutsaction是非线程安全的,大家可以参考一个RequestProcessor中定义的Map类型的actions字段,而Webwork是线程安全的,因为其ActionContext ThreadLocal的,也就是说每个线程都有自己的变量,互不干扰。具体体现是StrutsAction里面不能有字段申明,只能有局部变量。而Webwork可以,这对于获取页面表单数据非常方便。

6.       请求应答

Action执行完毕后,我们应该为其导航到结果页面,

webwork里面,也就是Result Type。它定义了好几种方式。比较有意思的是它处理象freemakerhtml模板),XML/XSLT,PDF这些格式输出。而Struts基本上是很单一JSP

而且webwork还可以自定义Result类型,可以为我们提供Swingmobile客户端显示。

7.       异常处理

任何操作都有出错的可能,怎么优雅地处理错误,这也是每个框架都应该考虑的。

有一些异常处理最佳实践,《Effective Java》就专门有一章谈到。在OnJava上也有一篇文章:http://www.onjava.com/pub/a/onjava/2003/11/19/exceptions.html,非常值得一读。

1.选择Checked还是Unchecked

2Exception的封装

3.如无必要不要创建自己得Exception

4.不要用Exception来作流程控制

5.不要轻易的忽略捕获的Exception

6.不要简单地捕获顶层的Exception

StrutsWebwork里面都支持异常处理,webwork是通过Interceptor支持的:ExceptionMappingInterceptor

在我的项目实践中,我喜欢将业务异常封装在业务层,申明为checked ExceptionwebAction必须捕获,获取exceptionErrorCode,此ErrorCode就是resource文件里面的key,也就是说它支持多语言,如ErrorCode.USER_EXISTED=”error.user.userExisted”。这类信息应该是业务层抛出的。如果将它由action处理,这是一种设计上的错误。

8.       灵活性、扩展性、可插入性

作为框架,就应该保证其灵活,支持不同用户的业务需求;容易扩展其功能,插入系统级的功能。

Struts而言,在可插入性上还是不错的,这得益于它的plug-in支持,实现其PlugIn接口,然后在其struts-config.xml文件中配置一下,如它的验证框架、网页布局Tiles,内存数据库,都是其典型应用。

另外,以前的Struts还可以扩展它的RequestProcessor,实现一些特有的功能,如日志、安全,因为它预留了一个缺省方法processPreprocess()

Webwork也是高度可扩展的,它主要是通过实现Interceptor接口。

9.       模块、组件化

在大型web项目中,模块、组件这些概念就非常适用了,因为一个大的工程,可能由不同公司开发,或是不同项目组、不同成员协作开发,最后要很容易地集成在一起。另外,还有第三方公司开发的组件插入进来,如漂亮的web界面组件,如Treetable等。

Tapestry就是一种基于组件的开发框架,不过我没有研究,呵呵。

webwork确实可以支持,如xwork.xml 配置的package就是支持模块申明,其附带的FreeMaker就可以将开发好的模块打包成jar文件,在Servlet容器外加载。

JSF对组件支持是相当到位的。它所设计的目标,就是在IDE里面,直接拖拽web组件,象tabletree,就可以形成漂亮的界面,真正实现所见即所得。实现自己的组件,只要实现其UIComponent接口就行了。应该说JSF是一种非常有前途的Web层框架,它会把Web开发真正达到easy。因为直到现在,还没有一种框架能够很容易做到,它的界面开发始终没法和微软相提并论,虽然它有界面布局框架TilesSiteMesh,以及模板语言VelocityFreeMakerServlet2.4支持的EL

不过遗憾的是,JSF开发工具还没有达到那么完善,除了Sun自己一直、推广的NetBeans IDESun的官方有其demo,用flash演示,还是蛮cool的。

 

关于Ajax和请求模式

Ajax其实早在五年前就有了,只是没有被人注意罢了,直到2005google把它应用在google mapgmail上,才开始被人关注。它也是web2.0时代一种重要的技术,ajax强调用户体验(XP)。因为它的本质就是一个异步调用。而我们的一般web页面请求都是同步的,你必须等到服务器全部处理完成。同步变异步,确实是一种革命,虽然它的技术很简单,只是一个XMLHttpRequestjavascript对象。它让我们的Web版的Rich Client成为可能。Google现在正看到了web office的应用前景,对MS构成巨大威胁,大家可以试试它的Web版的excel和、日历、邮件,不久就会推出正式的web word,很cool

另外,Ajax更接近实际的web请求,因为一般web请求时,每一次,我们获得的是整个页面内容,无论这个页面有多少数据是冗余的。譬如,我们分页浏览时,整个页面布局是由headerleft navigatorfooter组成,中间是content,翻页时,应该从服务器返回一个xml的用户列表数据格式,而且不包括html tabletag,这正是ajax另外一个方面:返回的是数据,而不是整个页面。这对于窄带宽,也是非常有益的。

Webwork2.2.2版本支持ajax,底层是dojoDWR这两个著名的ajax框架。但是webworkajax Tag做得太粗糙,用了ajax后,页面布局,特别是表单位置没法控制,而且对IE浏览器支持不够。我现在几乎都放弃了。

没有好的ajax框架,使得ajax开发起来很困难,也许因为它还不到一周岁吧。

我们现在的web框架,一般都是基于请求的模式,也就是说我们请求时总是会考虑它的目的URL,将提交数据保存在该请求中。这种模式,让我们开发时总在考虑这些所谓的http协议。一种完善的框架,应该尽量去屏蔽这些与底层协议相关的东西。

JSF给我们一种全新的方式,它让我们按照操作桌面应用,如Swing程序的方式处理网络请求,因为它是基于事件的。在SunpetstoreWAF框架中就有这种原始的思想。基于事件,让我们开发rich client提供了一种思想。

事件驱动有一种核心的模式,那就是Observer模式,所谓的Observer就是listener(只是一个用眼睛,一个用耳朵,呵呵)。Oberver是一种推(push)模式,也就是说事件Event发生时(如model发生改变),它会通知你,而不是你去取(拉模式)。

Servlet规范中,也引入了listener的概念,如HttpSessionListener,它对于监视用户上线下线非常有帮助,它们是生命周期lifecycle的范畴。

分享到:
评论

相关推荐

    webwork源码底层实现

    webwork底层源码,用于webwork框架设计

    Webwork2开发指南

    这里我们所谈及的WebWork,实际上是Webwork+XWork的总集,Webwork1.x 版本中, 整个框架采用了紧耦合的设计(类似Struts),而2.0 之后,Webwork被拆分为两个部分, 即Webwork 2.x +XWork 1.x,设计上的...

    WebWork2开发指南

    WebWork,实际上是Webwork+XWork的总集,Webwork1.x 版本...整个框架采用了紧耦合的设计(类似Struts),而2.0 之后,Webwork被拆分为两个部分, 即Webwork 2.x +XWork 1.x,设计上的改良带来了系统灵活性上的极大提升

    WebWork开发指南

    这里我们所谈及的WebWork,实际上是Webwork+XWork的总集...整个框架采用了紧耦合的设计(类似Struts),而2.0 之后,Webwork被拆分为两个部分, 即Webwork 2.x +XWork 1.x,设计上的改良带来了系统灵活性上的极大提升。

    webwork hibernate spring 实现留言板,远程登录

    用到知识是webwork做表现层 spring的事务层,IOC AOP hibernate 数据库的映射 Model view control传说中的三层+service 数据库是sqlserver 2005 更重要的是提供所有的.jar框架包

    浅谈Struts2与Webwork的不同和相同点

    绍Struts2与Webwork的不同和相同点

    webwork in action 第二卷(高清中文版2/3)

    个人认为本书是学习struts2的最佳参考书,其最牛逼之处在于不仅让你知其然,还会知其所以然,其字里行间流露出的框架设计理念非常精彩,深刻而又清晰,每每让我拍案叫绝。同时本书对细节的把握又恰到好处,不会因为...

    webwork in action 第一卷(高清中文版1/3)

    个人认为本书是学习struts2的最佳参考书,其最牛逼之处在于不仅让你知其然,还会知其所以然,其字里行间流露出的框架设计理念非常精彩,深刻而又清晰,每每让我拍案叫绝。同时本书对细节的把握又恰到好处,不会因为...

    webwork in action 第三卷(高清中文版3/3)

    个人认为本书是学习struts2的最佳参考书,其最牛逼之处在于不仅让你知其然,还会知其所以然,其字里行间流露出的框架设计理念非常精彩,深刻而又清晰,每每让我拍案叫绝。同时本书对细节的把握又恰到好处,不会因为...

    struts2建立流程

    Struts 2是Struts的下一代产品,是在 struts 1和WebWork的技术基础上进行了合并的全新的Struts 2框架。其全新的Struts 2的体系结构与Struts 1的体系结构差别巨大。Struts 2以WebWork为核心,采用拦截器的机制来处理...

    Webwork 实现文件上传下载代码详解

    WebWork 当然也提供了很友好的拦截器来实现对文件的上传,让我们可以专注与业务逻辑的设计和实现,在实现上传和下载时顺便关注了下框架上传下载的实现。 1. 包装 Request 请求 •每次客户端请求 Action 时,都会...

    简易J2EE web框架EasyJWeb源码

    EasyJWeb是基于java技术,应用于WEB应用程序快速开发的MVC框架,框架设计构思来源于国内众多项目实践,框架充分借签了当前主要流行的开源Web框架(Struts、JSF、Tapestry 、Webwork),吸取了其优点及精华,利用...

    尚硅谷_SpringMVC.docx

    基于Spring4.x、涵盖企业开发技术点、源码级讲授的尚硅谷_SpringMVC。 ...SpringMVC在框架设计、扩展性、灵活性方面全面超越了Struts、WebWork MVC框架,从原来的追赶者一跃成为MVC框架的领跑者。

    struts2的核心包

    框架设计的目标贯穿整个开发周期,从开发到发布,包括维护的整个过程。  Apache Struts 2即是之前大家所熟知的WebWork 2.在经历了几年的各自发展后,WebWork和Struts社区决定合二为一,也即是Struts 2。

    Struts2及其环境搭建

    框架设计的目标贯穿整个开发周期,从开发到发布,包括维护的整个过程。  Apache Struts 2即是之前大家所熟知的WebWork 2。在经历了几年的各自发展后,WebWork和Struts社区决定合二为一,也即是Struts 2.

    简易Web框架EasyJWeb源码

    EasyJWeb是基于Java技术,应用于WEB应用程序快速开发的MVC框架,框架设计构思来源于国内众多项目实践,框架充分借签了当前主要流行的开源Web框架(Struts、JSF、Tapestry 、Webwork),吸取了其优点及精华,利用...

    EasyJWeb框架 v0.5

    基于java技术,应用于WEB应用程序快速开发的MVC框架,框架设计构思来源于国内众多项目实践,框架充分借签了当前主要流行的开源Web框架(Struts、JSF、Tapestry 、Webwork),吸取了其优点及精华,利用Velocity作为...

    struts-2.3.16.1.zip

    Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互。Struts 2是Struts的下一代产品,是在 struts 1和WebWork的...

    JAVAEE主流框架之SpringMvc框架实战开发教程(源码+讲义

    课程简介: 基于Spring4.x、涵盖企业开发技术点、源码级讲授...SpringMVC在框架设计、扩展性、灵活性方面全面超越了Struts、WebWork MVC框架,从原来的追赶者一跃成为MVC框架的领跑者。 课程主要内容: 课程部分讲义:

    struts2总结

    struts2是一个MVC框架,以WebWork框架的设计思想为核心,吸收了Struts 1的部分优点, 拥有更加广阔的前景,自身功能强大

Global site tag (gtag.js) - Google Analytics