Lightweb 思路探讨
《Web开发构想》帖子里面,我写了一些关于Web Framework方面的想法。
http://forum.iteye.com/viewtopic.php?t=13432
Lightweb就是这些想法的实现。目前,编码工作初步完成。具体功能方面基本按照自己的思路实现了。这里主要阐述一下lightweb的功能、用法、特性。以此来获取大家的真知灼见,以便lightweb的改进。Thanks for your discussion.
1. Lightweb的目标领域
我感觉,Struts, WebWork, SpringMVC, Tapestry, JSF 等的目标领域一般是 类似Desktop, Rich Client等交互性很强的内部应用系统(URL种类有限,菜单有限)。
Lightweb的目标领域是 大型的内容服务网站(URL种类无限可扩展,无限制的子模块层次和个数)。所以,实现和用法的侧重点都有不同。
Struts 等注重Validation, Population, Taglib, Page Component等。工作基本花在View上。
需要配置站点地图,每个URL类别都要对应一个Action Class,并且每个Action还要配置对应的Page File。Lightweb的第一要务,就是要消除站点地图的手工配置,具体做法是,利用规则匹配代替直接指定。工作基本花在Dispatcher,Controller上面。Lightweb直接支持URL美化,不需要另外的filter, 因为Lightweb主要以URL为中心工作。
2.具体用法
比如,我们有这样一组URL的Pattern。
http://site.com/en/dir/category/area/beijing
http://site.com/cn/dir/category/area/beijing
http://site.com/en/dir/category/business/car
http://site.com/cn/dir/category/business/car
http://site.com/en/dir/index/1001
http://site.com/cn/dir/index/1001
我们可以看到,这些URL是分段的。每一段代表 一级子模块。后面的段属于前面的段。我们就来分析 dir/category/business/car 这一段吧。4级子模块。
Lightweb是这么定义的。除了最后一级,前面的各级子模块,都对应一个 Channnel (其实就是Dispatcher);最后一级子模块,可以对应 Channel (Dispatcher), Controller (类似于SpringMVC的Controller), Action(类似于WebWork的Action)等三种编程模型。
这里可能难以理解。Struts等,再怎么分package,一个URL就是直接对应到一个Class。而Lightweb在上述的例子中,却一步步对应了4个Class。前3个是Channel Class,最后一个可能是Channel, Controller, Action等Class。
DirChannel
----CategoryChannel
--------AreaChannel
------------BeijingChannel ( or BeijingAction, BeijingController)
--------BusinessChannel
------------CarChannel ( or CarAction, CarController)
----IndexChannel (or IndexAction, IndexController)
规则匹配可以这样简单定义:
en -> “”
cn -> “”
postfix -> “Channel”
匹配引擎找到了en, cn,都有定义,向下走,然后遇到dir,这个时候,没有找到dir的定义。
匹配引擎这个时候,就把dir -> DirChannel, 并装载DirChannel类。
DirChannel类接着向下走(注意这个时候,DirChannel自己变成了匹配引擎,它有自己的匹配规则,这里的匹配规则只有一条 postfix -> “Channel”),遇到了area,没有发现area的定义,那么就把area-> AreaChannel,并装载AreaChannel类。
AreaChannel类接着向下走(注意这个时候,AreaChannel自己变成了匹配引擎,它有自己的匹配规则,这里的匹配规则只有一条 postfix -> “Action”),遇到了beijing,没有发现beijing的定义,那么就把beijign-> BeijingAction,并装载BeijingAction类。
然后执行BeijingAction,返回结果。
可以看到,程序员可以定制任意级别的Channel。而不需要维护一个统一的庞大的站点地图。在同一个子模块内,增加一个Service,不需要改动任何配置文件。如果需要加入一级子模块,只要定义一个简单的匹配规则即可。找到了Service之后,如果URL还没有用完,那么后面的URL片断,都转化为参数(“/”分隔)。
上面说明了如何根据URL分级别找到 Service Class。下面来看如何寻找View。
Struts等,view, action都是配置在一起。而Lightweb则完全分开独立处理。
比如,http://site.com/cn/dir/category/business/car
模板引擎装载 cn/dir/category/business/car.html 这个文件。(前缀、后缀可以订制)
如果Service返回了一个View Name,比如,edit。那么,模板引擎装载 cn/dir/category/business/car/edit.html 这个文件。
如果Service返回了一个View Name,比如,../carEdit。那么,模板引擎装载 cn/dir/category/business/carEdit.html 这个文件。
1 楼
nihongye
2005-08-30
Lightweb就做url美化,没了?
你说的东西大概明白,但不知道你想干什么。
你说的东西大概明白,但不知道你想干什么。
2 楼
buaawhl
2005-08-30
nihongye 写道
Lightweb就做url美化,没了?
你说的东西大概明白,但不知道你想干什么。
你说的东西大概明白,但不知道你想干什么。
比如,Struts / SpringMVC / WebWork 等的config文件里面,
配置了 几百条 url - action class - view mapping. 也许需要分成十几个文件存储。
Lightweb只用一两行规则,就可以搞定。免配置。
3 楼
Readonly
2005-08-30
偶们可以写一个Filter,让这个Filter先解析URL,再写一个ActionFactory,根据解析的结果执行对应的Action,返回到对应的View
只是在SpringMVC/WebWork的基础上加一层皮,没有必要做一个Web FrameWork吧?
只是在SpringMVC/WebWork的基础上加一层皮,没有必要做一个Web FrameWork吧?
4 楼
buaawhl
2005-08-31
Readonly 写道
偶们可以写一个Filter,让这个Filter先解析URL,再写一个ActionFactory,根据解析的结果执行对应的Action,返回到对应的View
只是在SpringMVC/WebWork的基础上加一层皮,没有必要做一个Web FrameWork吧?
只是在SpringMVC/WebWork的基础上加一层皮,没有必要做一个Web FrameWork吧?
这个 ActionFactory 的实现,要考虑 AOP, Interceptor 等的加入,相当于 WebWork 的 核心功能的实现了。还要考虑和其他的code 兼容合作,工作量比重新做一个Web Framework大多了。
还有就是,希望同时支持 Dispatcher Channel, SpringMVC Controller, WebWork Action.
比如,不需要request, session, servlet context 的简单情况,就使用 Action。需要request, session, servlet context 的时候,就使用Channel, controller. 直接在接口级别支持,而不必如WebWork那样需要通过Interceptor 或者 Thread Local 。
还有就是,给程序员更多的控制定制 Dispatcher 的能力,如果Canonical 的JSPLet 的思路。
5 楼
Readonly
2005-08-31
buaawhl 写道
这个 ActionFactory 的实现,要考虑 AOP, Interceptor 等的加入,相当于 WebWork 的 核心功能的实现了。还要考虑和其他的code 兼容合作,工作量比重新做一个Web Framework大多了。
只要写2个类就可以,没有你想象的那样多,比如WebWork就自带了一个CoolUriServletDispatcher,能够解析http://HOST/ACTION_NAME/PARAM_NAME1/PARAM_VALUE1/PARAM_NAME2/PARAM_VALUE2
成
http://HOST/ACTION_NAME?PARAM_NAME1=PARAM_VALUE1&PARAM_NAME2=PARAM_VALUE2
这个做法就和你处理action以后的参数是一样的做法了,你可以看看它的代码,真正处理的逻辑只不过10行而已。
如果你想处理前面的mapping逻辑,则可以利用namespace和actionname,动态构建一个action,也只需要扩展xwork的ActionProxyFactory即可,你也可以看一下DefaultActionProxyFactory,用它去实现你想要的功能,代码要稍微复杂一些,可能需要30-50行吧。
6 楼
buaawhl
2005-08-31
Readonly 写道
buaawhl 写道
这个 ActionFactory 的实现,要考虑 AOP, Interceptor 等的加入,相当于 WebWork 的 核心功能的实现了。还要考虑和其他的code 兼容合作,工作量比重新做一个Web Framework大多了。
只要写2个类就可以,没有你想象的那样多,比如WebWork就自带了一个CoolUriServletDispatcher,能够解析http://HOST/ACTION_NAME/PARAM_NAME1/PARAM_VALUE1/PARAM_NAME2/PARAM_VALUE2
成
http://HOST/ACTION_NAME?PARAM_NAME1=PARAM_VALUE1&PARAM_NAME2=PARAM_VALUE2
这个做法就和你处理action以后的参数是一样的做法了,你可以看看它的代码,真正处理的逻辑只不过10行而已。
如果你想处理前面的mapping逻辑,则可以利用namespace和actionname,动态构建一个action,也只需要扩展xwork的ActionProxyFactory即可,你也可以看一下DefaultActionProxyFactory,用它去实现你想要的功能,代码要稍微复杂一些,可能需要30-50行吧。
WebWork的这个扩展功能不错。
CoolUriServletDispatcher做了类似于URL Rewriter 的URL 美化工作。
DefaultActionProxyFactory 可以订制产生自己的ActionProxy. 不过好像支持一级nameSpace。
另外,即使这么做了。WebWork是否还是需要一个统一的中心配置控制文件?Lightweb的主要目的,就是分散控制中心。程序员定制自己的Channel Dispatcher,遇到相应URL的时候,自动转向一个独立的子模块,完全是 Service Name (URL) oriented。这样在开发大型网站的时候,不用考虑统一的控制文件,不会相互影响。做好自己的子模块(包括子模块控制中心、相应的应用程序),打包为一个jar, 扔在Web Server里面,就可以了,不需要在任何配置文件里面指明关于这个模块的任何信息。
如我前面所说,支持WebWork的Action编程模型,只是Lightweb的3种编程模型之一。还支持SpringMVC, 和特有的Channel Dispatcher模型。重点还是特有的Channel Dispatcher模型,让程序员完全控制Dispatcher,体现Cannonical的JSPLet的思路。
我并不觉得,WebWork的Action 编程模型适合所有情况。比如,用户需要直接控制request, session, servletcontgext的情况。所以,提供了上述3种编程模型。
虽然我以前为AOP辩护,但是对于这种修改Bytecode, 走上“邪路”的AOP/Interceptor,我不是很赞成。与其这样的AOP or Interceptor,还不如用OO。
Lightweb尽量在每个层次上都留有Injection Interface (or your can say, hook, handler, callback, etc),程序员可以利用IoC 容器等手段,把各种功能组织起来,组合为一个需要的Service。
Channel 包含 Controller;Controller 包含 Action。如果要截获某些Action,那么把功能注入到包含这些Action的Controller里面。如果要截获某些Controller, 那么把功能注入到包含这些Controller的Channel里面。比如,权限检查等工作。
从DispatchServlet接受的第一个Channel开始,Lightweb就允许程序员自己订制。所以,Lightweb的几乎所有的API都是暴露出来的。尽量方便程序员,充分利用OO 特性,达到几乎所有的特殊需求。
从另一个角度来说,Lightweb能够定制的东西太多,并不是一个快速开发框架。比较适合URL Pattern无限增长的网站类型。
7 楼
goldrain
2005-09-01
不错,action免配置。
我最近也对webwork改造了下,action可以不用配置了,直接解析url用隐含规则激活。
我最近也对webwork改造了下,action可以不用配置了,直接解析url用隐含规则激活。
8 楼
buaawhl
2005-09-01
goldrain 写道
不错,action免配置。
我最近也对webwork改造了下,action可以不用配置了,直接解析url用隐含规则激活。
我最近也对webwork改造了下,action可以不用配置了,直接解析url用隐含规则激活。
好.开源吗?
和ReadOnly说的方法类似吗?
9 楼
goldrain
2005-09-01
buaawhl 写道
好.开源吗?
和ReadOnly说的方法类似吗?
和ReadOnly说的方法类似吗?
开源的,不过我要剔除项目中的业务代码才能放上来。
和readOnly不大一样,比较简单,比如:
sys_portQuery.do就激活:xxx.sys.PortQueryAction
而result="/sys/contry"表示用"/sys/contry.html"模版展示动态内容,用"xxx.sys.CountryView"类处理页面逻辑。由此省掉了xml配置,而且文件的命名也得到规范和统一。
在写一篇“动态语言的启示”,完了一起放上来