??xml version="1.0" encoding="utf-8" standalone="yes"?>
<g:javascript library="dojo" />
<g:javascript>
dojo.require("dojo.io.IframeIO");
</g:javascript>
<g:form url="[action:'submitToRemoteCall']" id="form2"
enctype="multipart/form-data">
File: <input name="someFile" type="file"></input>
<g:submitToRemote
value="Submit Upload"
name="form2"
action="submitToRemoteUpload"
update="[success:'message',failure:'error']" />
</g:form>
在controller中写?br />
def submitToRemoteUpload =
{
def f = request.getFile('someFile')
if(f.empty) {
render "No file!"
} else {
def fileName = f.getOriginalFilename()
render(text:"<html><body><textarea>You called ${actionName} in
${controllerName} with file ${fileName}</textarea></body></html>",
contentType:"text/html", encoding:"UTF-8")
}
}
如果要返回render view?可以修改dojo的dojo.io.bind()Qbind参数加上mimetype:"text/html"。form中的<g:submitToRemote>改ؓ
<input onclick="dojo.io.bind({url:'/test/index/submitToRemoteUpload',
mimetype:'text/html',
load:function(type,data,evt){dojo.byId('message')innerHTML = data.body.innerHTML;},
error:function(type,error) { dojo.html.textContent( dojo.byId('error'),error.message);},
formNode:dojo.byId('form2')});return false"
type="submit" name="form2" value="Submit Upload">
]]>
能够q行Web开发的~程语言和技术很?
(1) 动态解释语a
PHP; Perl; Python (Zope, Plone); Ruby (Ruby on Rails);
(2) ~译语言
Java; .net
Java Web开发远非一枝独UQ?
除了受到来自.net q个重量U对手的最大挑战之外,更受到Zope, Ruby on Rail {新式轻骑兵的冲击(当然Q也l箋受到老式L兵PHP, Perl的冲击)?
官方Java走的是复杂\U,Servlet -> JSP -> Taglib?net走的也是复杂路线Q依靠成熟友好的集成化开发环境取胜。Java阵营好容易应对过来,从纷U复杂的各种开发框架基上,发展Z重量UWeb开发框架JSFQ以及相应的集成化开发环境;渴望以此应对.net的攻ѝ胜负未分,前途未卜。这Ӟ另一个方向又杀来了新式轻骑Zope, Ruby on Rail?
Python, Ruby{动态解释语aQ面向对象特性更好,先天支持 动态绑定、AOP、函数式~程?#8220;~程即配|?#8221;{时髦概c开发速度更快Q代码量更小Q达到killerU别?
传统的HTML Web开发领域里面,Java已经是腹背受敌。领域外也展开了征战,Rich Client Architecture的兴PAJAX(XMLHttp), Flash RIA, XUL, XAML, Smart ClientQ以及从前的ActiveX, Applet, Web StartQ?
Web的发展趋势是 语义WebQ最l目的是让整个Web成ؓ一个巨大的数据库?
q意味着Q未来的Web应用更加的面向文本内容数据Q更加搜索引擎友?– Search Engine Friendly.
二进制的客户端插Ӟ如Flash RIA, ActiveX, Applet, Web Start{,虽然交互性能最好,但不是以文本内容数据Z心,搜烦引擎不友好。所以,我只是保持适当x。我更关注基于文本的UI表现Q如HTML, XUL, XAML{。XUL, XAMLq没有广泛流行,只是保持一U有兴趣的关注?
当下x的重点,q是 XHTML + CSS + Javascript量?AJAX(XMLHttp)增加更好的交互性?
我一直认为:轻量、简z、高?才是道理。后面阐q我对Java Web开发的理解和构惟?
2. Web开发框架层ơ概q?
从上CQWeb开发框架的层次如下Q?
(1) HTML, JavaScript, CSS{页面资源?
(2) 面模板层?如JSP, Freemarker, Velocity, XSLQfastm{。用来生成HTML, JavaScript, CSS{页面资源?
(3) Web框架。把HTTP Request调度分派到对应的Service Entry?
(4) Business Logic.
(5) O/R Mapping.
(6) JDBC
(7) DB
Ҏ我的l验Q一个典型的Web应用中的代码比例如下Q?
面逻辑U占 50%Q商业逻辑U占30%, O/R U占20%?
但事实上Q页面却是最不受重视的部分,从来都被认ؓ是脏z,累活Q杂zR典型的开发过E通常是这P
面设计人员q速的用Dreamweaver{生成一堆文本杂乱无章的面Q然后交lJSPE序员加入更加杂乱无章的Java代码和Taglib?
当页面布局风格需要改变的时候,面设计人员用Dreamweaver{生成一堆新的页面。JSPE序员再重新加入更加杂ؕ无章的Java代码Taglib?
至于面中的脚本逻辑调试Q更是一门精q工夫了?
ҎC会规则Q通常来说Q工作内容越LQ收入越高;工作内容脏月篏Q收入越低;Web开发也是如此:做着最脏最累的zȝ面E序员,工资一般比不上后台业务逻辑E序员?
开发框枉常会带来这Ll果Q让单的东西Q变得更单;让复杂的东西Q变得更复杂?
q其中的原因在于Q?
一般来_一个应用中单重复的东西?0%Q复杂特D的东西?0%?
单重复的东西很容易摸清规律,q行包装Q通用化。但是,在包装的同时Q经常就L住了底层的一些灵zd大的控制能力。在复杂Ҏ的需求中Q确实又需要这些底层控制能力,那么Zl开框架的限Ӟ付出的努力要比不用框?大得多?
打个比方Q一个比较极端的例子。编译语a比汇~语a的开发效率高很多Q但是却无法直接操作寄存器。当需要在~译语言中操作寄存器的时候,非常的痛苦。比如JavaQ也讔R要JNIQ写C代码Q还要在C代码里面嵌入汇编。编译、连接都很麻烦?
所以,一个框架的开发效率,在于这?0%??20%复杂之间的^衡?
假如Q不用框架来开发,单的80%要消?80个资源数Q复杂的20%要消?0个资源数Q总资源数?00Q用了某个框架Q简单的80%只要消?0个资源数Q复杂的20%要消?0个资源数Q总资源数?0。那么,我们_q个开发框架是有效率的?
我的思\是,同时应对复杂和简单。当ӞZ应对复杂Q简单的东西可能应对得不那么好。比如,做这样一个开发框Ӟ单的80%要消?0个资源数Q复杂的20%要消?0个资源数Q总资源数?0?
q种开发框架是有可能实现的。而且是很有意义的。尤其是在复杂部分的比例提高的时候。越复杂的系l,q种开发框架就有意义?
后面的关于Web各层开发的Q主要就按照q个“应对复杂、让复杂更简?#8221;的思\展开?br />
3Q页面资?
也许有h会说Q页面资源,不就是HTML吗?太简单,太低极了Q没劌ӀDreamweaver、Frontpage多简单阿。随便找个h来用可以了。文本内容ؕp糟不要紧,览器里面显C出来的效果好看p。要增加炫的、酷的动L果,那就写JavaScript呗。写在HTML里面Q看看在IE里面能不能运行就可以了呗?
q也正是大多数公司开发页面资源的方式。因为页面的需求变化是最多、最快的Q而页面的制作成本很低Qh们不愿意在上面投入更多的资源?
我的看法是,万丈高楼q_赗应用程序的每一个部分都应该完善理Q结构优。越是需求变化多的地方,是脏ؕ差的地方Q越应该加大力度处理好?
面l构斚wQJavaeye论坛的Dlee做了很多工作?
(1) ?2005 q我们如何写 JavaScript
http://forum.javaeye.com/viewtopic.php?t=12973
(2)使用 Unordered Lists 制作的下拉菜单和?
http://forum.javaeye.com/viewtopic.php?t=12995
从上面的Dlee的论q和l出的资料。可以看出,面资源分ؓ三部分:
(1) XHTML。结构,Structure?
XHTML里面的Tag部分只应该包?<ul> <table> <p> <div><span>{结构布局TagQ或?lt;strong><emphasis>表示语义的Tag?
XHTML里面不应该包括风g息,比如字体、颜艌Ӏ大、粗l等Q也不应该包?lt;font> <b> <i> <h> {字体信息?
XHTML里面不应该包括Javascript的定义和调用?
(2) JavaScript。行为,behavior?
JavaScritp应该存在于一个独立于XHTML文g的独立文件中。这样可以做自动化单元测试。JavaScript应该只改变HTML DOM的结构和内容Q而不应该改变它的风格?
(3) CSS。StyleQ风根{或者说QPresentationQ表现?
前面说了QXHTML里面不应该包括JavaScript的调用。那么,XHTML的元素是如何JavaScript事gl定hQ就是在CSS里面指定的?
当然Q众所周知QCSS的本职工作是处理面风格?
面资源斚wQ我完全认同Dlee的观炏V从技术和资源U篏的长q目标看来,q方面的初期投入的回报将是非怸厚的?
即ɞ来HTML消亡了,q入了XAML, XUL, RSS时代Q这些结构清晰的各部分,重用的可能性都非常巨大。JavaScript + CSS + XML UI的这U经典设计思\Q将留存很久。杂成一团的HTML的命q只能是全盘被抛弃?
4Q页面模板层
面模板层是指Server端运行的用来生成HTMLQ或JavaScriptQCSSQ的Server Side Template Engine?
q一层也是著名的脏ؕ差楼层。著名的HTML的Java代码污染事gQ就发生在这个楼层。不仅JSP有这个问题,其他的template, 如freemarker, velocity, tapestry{含有逻辑的脚本,都不同程度上有HTML的Script Logic污染问题?
Dlee的做法很。直接就不要面模板层,不用Server Side Template Engine。直接用JavaScript更改HTML DOM的结构、内宏V数据。同Ӟ会用到少量的览器端XSL?
q样带来的结果,Template是很干净Ua的HTMLQ不含有MServer Side Script。这个效果,和Servier Side Template ?JivanQXMLC辑ֈ的一栗只是一个是在浏览器端执行,一个是在Server端执行?
我研I比较了几乎所有的Server Side Template EngineQ力N众家之长Q避众家之短Q写了一个Server Side Template Engine -- fastm, 能够最优雅方便的实现页面模板层。关于fastmQ我的Blog上有不少文章?
我的BlogQ里面专门有个fastm 分类?
http://blog.csdn.net/buaawhl
http://buaawhl.blogdriver.com
Fastm发布在java.net上?
https://fastm.dev.java.net
我仍然对Server Side Template Engine持肯定态度。基于如下原因:
(1) JavaScript代码量大、文件多的时候,不容易管理,不容易进行语法检查,不容易跟t调试?
q里有h会争辩,Server Side Template Engine也用C很多脚本阿,比如Freemarker, Velocity, 而且嵌在HTML中,怎么理Q怎么调试Q即使是JSPQ也是Java Code嵌在HTML里面Q怎么理Q怎么调试Q?
q里我要_Jivan, XMLC, fastmQWicket{Template Engine的逻辑都是在Java Code里面?
(2) 用JavaScript生成文本内容Q搜索引擎不友好?
一般的|络蜘蛛E序Q只ҎURL获取HTML文本Q搜索里面的文本内容Q而不会执行里面的JavaScript脚本?
(3) JavaScript代码重用q是有些局?
比如Q有两个HTML文gQ一个是Table布局Q一个是List布局?
我有同样的一Ҏ据,要在q两U布局中显C?
q时候,pl这两个HTML分别写两套JavaScript。这里面的DOM层次Q元素,属性都不同Q再怎么定义IDQClassQ也无法用完全相同的一套JavaScript处理?
q里有h会争辩,Server Side Template Engine也无法做到。别说JSP, Velocity, Freemarker{要在两套HTML里面嵌入相同的代码,是Jivan, XMLC, Wicket也要分别写不同的两套Java CodeQ因为它们的XML DOM Node / Model View (Table, List) 都是不同的?
q里我要说。fastm可以做到只用一套代码逻辑。而且只有fastm可以。fastm的代码重用率是最高的?
关于Ajax(XMLHttp)Q我的意见是必要时才用,而且最好采用粗_度的用?-- JavaScript发出一个URLhQ返回一整段HTMLQ直接替换到面的某一块,而不是用JavaScript来做q样的把数据填充到HTML DOM中。如果你直接在浏览器里面输入那个URLQ也可以获取那整D늚HTML内容?
典型的应用场合是Portal。Portal面的每个Portlet都含有这L Ajax(XMLHttp) javascript代码 -- 发出一个Portlet URLhQ返回一整段Portlet的内容,直接替换当前的Portlet块?
q样做的好处是:
(1) 减少JavaScript代码的量和复杂度?
(2) 搜烦引擎友好。网l蜘蛛程序可以L别JavaScript中的URLQƈҎq个URLQ获取整D处理好的HTML文本Q进行内Ҏ索?
有h可能会争辩:如果URLhq回的是XML数据Q不是整D处理好的HTMLQ搜索引擎也可以q行内容搜烦?
q点我同意。前提是XML数据的内Ҏ_q诏的,而不是散落的。比如,你返回的XML数据?#8220;中国”。这?#8220;中国”要放在HTML中的一个{country}位置Q{country}球。这个时候,l果HTML的内容含?#8220;中国球”。而XML数据中只含有“中国”。如果用L“中国球”作ؓ关键字来搜烦Q就找不到这个URL?
从前面给出的fastm资料的连接中Q可以得知。如同Jivan, XMLC, Wicket一Pfastm的template里面不含有逻辑Q所有的逻辑都写在Java里面?
有h会争辩说Q页面逻辑写在Java里面Q我改变了页面逻辑Q还需要重新编译。这也太不方便了。Velocity, Freemarker, JSP׃用重新编译?
q里我的看法是:业务逻辑代码改变了,不也需要重新编译吗Q页面逻辑׃是逻辑了吗QHTML里面的脚本怎么语法查、跟t调试?业务逻辑需要语法检查、跟t调试,面逻辑׃需要语法检查、跟t调试了吗?
Ҏ可能会说Q在我的应用中,面逻辑的改动需求非帔RJ,而且q些面逻辑非常单,不需要语法检查、跟t调试?
q里我的意见是:
(1) 那就使用JSP, Velocity, Freemarker{脚本?
(2) fastm, Jivan, XMLC, Wicket的Java代码部分也可以写在脚本里面,比如QServer Side JavaScript, Jython(Python), Groovy, Bean Shell {脚本语a都可以很方便的和Java怺调用?
fastm的生命周期将很长?
HTML, XUL, XAML都是Q或是可以在浏览器或可视化~辑工具里面昄的XML UI定义语言。Microsoft Office的Word, Excel, Powerpoint{格式都提供了相应的XML格式。这些XML文g都可以在Office里面昄Qƈ~辑?
Adobe公司也提供了PDF的XML格式 -- XDP。可以在Adobe Designer里面昄q编辑?
׃fastm是Designer Friendly的XML UI所见即所得的模板技术。这斚wh很大的潜力?
Ҏ不需要第三方花大力气专门做个IDEQ来昄自定义的Tag。目标文件格式提供商自己的阅ȝ辑工具就可以直接用了Q而且效果是q行后生的l果文g的效果?
即没有可视化要求的场合。比如,Web Service需要的XML数据。fastm同样有用武之地。比如,
<!-- BEGIN DYNAMIC: users -->
<user>
<name>{name}</name>
<address>{name}</address>
</user>
<!-- END DYNAMIC: users -->
可以很容易的把一个Java Object List转化为XML数据?
另外Q我不得不承认。浏览器端的JavaScript的页面逻辑Q可UL性要高于Server Side Template Engine。因为Server Side Template Engine通常是特定语a相关的?
目前fastm是用Java实现的。由于实现很单,UL到其它的语言Q也很简单。如果是UL到Python, Ruby{动态解释语aQ那更单了。我是有q个考虑Q因为Zope, Ruby on Rails 的模板还是Logic ?HTMLh的,fastmq个思\有很大的用武之地?
前面讲了q么多。清理了两层有名的脏乱差的老大隄楼层 -- 面资源层和面模板层。让q两层变得和下面的楼层同L优雅、清z?
下面该讲到Web框架层了。在向下讲之前,׃前面提到了脚本,我想先插入一D关?#8220;可配|?#8221;?#8220;可编E?#8221;?#8220;可热部v”?#8220;脚本逻辑 vs XML Tag逻辑”的话题。把q个Z比较兛_、讨论比较多的话题,先讲清楚?br />
5Q可配置、可~程、可热部|Ӏ脚本逻辑 vs XML Tag逻辑
׃Java是编译语aQh们通常把变化的参数部分抽取出来Q放到配|文件中?
q些配置文g通常是XML文g。这很好Q没什么问题。XML很适合用来表达数据l构?
但是Q对于某一U技术的狂热Q通常引v对这U技术的q度使用Q或者误用?
Z开始觉得,XML能够表达一切东西,包括for, if, else{逻辑。这斚w的典型例子有 Workflow XML DefinitionQLogic TagLib, XSL Logic Tag{?
q点我不敢苟同。我的看法是QXML不适合表达逻辑QXML表达逻辑非常y脚。XML表达逻辑相当于自定义一门XML格式的脚本语a?
比如QLogic TablibQ很难自然的支持 if else, switch。只能蹩脚地支持一?<logic:if> <logic:ifNot> <logic:exists> <logic:notExists> <logic:ifNull> <logic:notNull>?
Q注Q好久没有接触过Taglib了。这些Tag Name都是凭以前的使用印象写的Q也许名字不对,但表达这些意思的TagLib都还是有的)
如果要表达if () else if() else 更y脚了。要q行非常ȝ的嵌套?
再比如,XSL 支持if, else 也非常蹩脚。非要多出来一个层ơ才行?
<xsl:choose>
<xsl:when test="…">
…. If ….
</xsl:when>
<xsl:otherwise>
… else …
</xsl:otherwise>
</xsl:choose>
同样Q如果要表达if () else if() else 更y脚了?
<xsl:choose>
<xsl:when test="…">
…. If ….
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="…">
…. If ….
</xsl:when>
<xsl:otherwise>
… else …
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
可以看到QXML Tag 表达逻辑Q非帔R烦,可读性很差,完全是一U误用,没有半点优势。当Ӟ逻辑单的情况下,q是可以接受的?
有h会说QXML表达逻辑Q可以免~译ѝ?
那么我说Q语法检查呢Q跟t调试呢Q?
Ҏ_只是一些简单的逻辑Q不需要语法检查、跟t调试?
我说Q如果只是ؓ了免~译Q前面列出的那么多的解释执行的脚本语a更适合。XML表达的逻辑Q比Java{编译语aq要ȝ很多Q而脚本语a比Java{编译语az多了,可读性非常好Q而且脚本语言和Java语言有很好的交互性,可以怺调用。重用、结构方面都h优势?
有h会D?strong>Spring IoCZ子,_你看Q?strong>Spring IoC的配|文件不都是XML格式吗?
我说Q?
(1) Spring IoC的配|文件基本都是属性设|,Bean ID声明。没有逻辑?
(2) 我也不是很赞?strong>Spring IoC在XML配置文g里面引用Javacȝ做法。这斚wQ其它的容器?Pico, Nano都支持多U配|方式,其中包括了不脚本方式。我觉得Q在脚本里面定义生成Java ObjectQ比在XML中要好。当ӞWeb.xml里面也引用了Java Class名字。但那是非常单的情况。没有嵌套引用、属性赋倹{构造参数等复杂的定义方式。XML适合描述一些通用的资源、数据、结构。比如,HTML, XUL, XAMLQRSS是XML用的恰当的例子?
所以,我的基本观点是这栗?
(1) U数据,不用_应该定义在XML中?
(2) 如果是系l中一些Java Object要用到的基本属性。比如,q接池大等。定义在properties, XML, Script中都可以。如果定义中没有出现具体的Java Class名,們于定义在properties, XML文g中。如果出C具体的Java Class名,們于定义在Script中。这个界限不那么明显Q两者皆可?
(3) 复杂l构的Java Bean的构造生成,那是肯定会出现具体的Java Class名,应该定义在Script中?
关于“可配|?vs 可编E?#8221;Q有一点要明确Q只要是可编E的Q一定是可配|的。但如果是可配置的,却不一定是可编E的?
q里的可~程Q是指框架给E序员提供了APIQ可配置Q是指框架给E序员提供了配置文g的格式写法?
“可编E?#8221;一定是“可配|?#8221;的?
(1) 用户臛_可以自己定义配置文gQ读取参敎ͼ调用API?
(2) 有那么多的解释脚本可以直接和Java互操作,完全可以直接用来当作配置文gQ定义参数?
“可配|?#8221; 却不一?#8220;可编E?#8221;的?
如果框架只给你提供了配置方式Q而没有APIQ那意味着Q你只能q行参数的静态配|。很隑֜动态期间改变这些参C。你M能尝试着用代码去改变配置文g的内容吧Q即使你改动了,如果框架不进行文件的旉x查,是一开始装载进来,׃再检查更改了Q你不就一点办法都没有了吗Q?
比如QStruts Tiles的XML定义Q你只能静态配|,你想在运行期间改变布局Q没有办法。Site Mesh也是如此。而我们可以在q行期间L操作XML DOM NodeQ别说布局了,M东西都可以改变?
所以,一个框枉要注重的是提供APIQ而不是提供配|方式。这是一个重要的原则?
讨论完了“可编E?#8221;?#8220;可配|?#8221;问题Q我们来?#8220;热部|?#8221;问题?
XML配置文g、脚本文件支?#8220;热部|?#8221;当然要比~译语言E序的热部vҎ得多。只要解释执行前Q检查一下时间戳可以了。要注意的问题,只是做好试Q因为没有编译期的语法检查?
不过QJavaE序也是可以“热部|?#8221;的。只是稍微麻烦一炏V典型的例子是JSP, EJB Jar{。JSP修改之后Q会自动~译执行QEJB Jar丢到EJB Container里面Q会被检到q装载到JNDI命名I间?
~译语言JavaE序的热部v的一个可能的技术难ҎQClass或者Jar已经存在Q如何监到Class或者Jar的更改,q装载这个新版本Q替换旧版本?
q个问题我具体没有研I过。从道理上讲Q应该在Class Loader上下功夫。如果需要,可以参阅开源EJB Container的相兛_现部分。Javaq有一U?#8220;Hot Swap”技术,专门解决q个问题Q可以搜索查阅一下?
q段插Ԍ到q里。下面讨论Web框架?br />
6QWeb框架
Web框架层是一个清z的楼层。很多优U的程序员在这一层大展n手,做出了很多好作品。我感觉不错的有Spring MVC, Web Work?
对于Web应用来说QWeb框架层是最重要的一层。SOA、Semantic Web{效果都要在q一层实现?
首先Q我们来讨论Q框架的~程l构?
我的Blog中有一《Java Web框架lD》的文章。讲解了一些流行的Web框架的编E结构,很多重复的内容不再赘q?
http://blog.csdn.net/buaawhl
Java Web框架lD
http://blog.csdn.net/buaawhl/archive/2004/12/21/224069.aspx
Spring MVC的编E接口是最清晰的。大多数单情况下QWeb Work的用法是最单有效的Q编E结构比较特D,可以说具有一定的变革意义?
Spring MVC的Controller接口相当于Struts ActionQ也hRequest, Response两个参数Q虽然编E接口非常清C雅,但是本质上没有什么变化?
WebWork的Action则失MController的n份,只相当于FormBean的n份,或者说相当于ActionBean的n份?strong>WebWork Action不具有Request, Response两个参数Q它只具有属性,q过属性Setter获取HTTP Request的参敎ͼ通过属性getter把结果数据输出到HTTP Response?
可以_WebWork的这个把握是相当C的?5%以上的情况下Q程序员是不需要Request, Response参数的。当需要这些参数的时候,WebWorkq没有挡住\Q可以通过实现RequestAwareQResponseAware{接口来获取Q或者通过一个Thread Local获取。这U情况下Q编E结构的U定Q就不那么清C?
我从Canonical的帖子和Blog受到了很多启发?
http://canonical.blogdriver.com
jsplet:对Model 2模式的批?
http://canonical.blogdriver.com/canonical/591479.html
jsplet?strong>webwork的概念对?
http://canonical.blogdriver.com/canonical/594671.html
从列理论看MVC架构
http://canonical.blogdriver.com/canonical/579747.html
从Canonical的文章可以看出。JSPLet用JSP文g作ؓDispatcherQ然后在JSP里面注册q调用对应的Object。这个寻访Object的过E,完全是根据丰富的URL定义来做的。URL里面包括Object Scope, Object Name, Method Name, Method ParametersQ天生就对事件机制有良好的支持?
Zope的一些做法也有异曲同工之妙?
Zope Object Publishing
http://www.zope.org/Documentation/Books/ZDG/current/ObjectPublishing.stx
http://www.plope.com/Books/2_7Edition/ZopeArchitecture.stx#2-3
q种通过URL获取Published Object的服务的思\Q是一U实现SOA效果的有效思\?
我们首先来看Web Service的现状。目前Web Service主要分ؓ两大阵营。SOAP和REST。关于RESTQ请参阅
http://www.xfront.com/REST-Web-Services.html
关于SOAP和REST的比较、互操作Q网上有很多文章。如果需要请搜烦查阅?
我个人比较們于REST风格的Web Service?
因ؓSOAP是一门固定的协议Q如果用SOAP来编写Web ServiceE序Q需要一个SOAP协议的解析库 Q也许还需要一些专门的“SOAP 数据 -- ~程语言”映射库,如同CORBA IDL的多语言映射一栗如果你要让自己的Web应用支持SOAPQ你需要把发布的服务对象、方法都包装为SOAP协议Q这需要一些编E语a相关的数据结构的映射工作?
REST则只是一U风|而不是一个协议。中心思想是简单的通过丰富的URI定义 (如XLink + XPointer{? 获取资源。如果你要让自己的Web应用支持RESTQ那么很单,只要在URI上下功夫可以了Q比如,多增加一个参数format=RESTQ在E序中多增加一UXML输出格式可以了。(从道理上来说QSOAP也可以这么实玎ͼ但SOAP的输入和输出都要遵守SOAP协议QSOAP的输入参C般都包装在SOAP信封里面Q?
关于HTTP Get和PostQ我表述一下自q看法?
我认为,Web的精髓在于GetQ而不是PostQ在于获取服务器的输出,而不是输入到服务器。即QWeb的精髓在于以搏大,四两拨千斤。最l典的用法就是用一个URLQ获取一个长的文本内容Q这个内定w面充满了其他更多的资源连接。这也是文本连接HTML发明的初街?
至于HTTP PostQ则是这上面的一个扩展。B/Sl构如此行Q很多应用都要{UdWeb上面Q怎么办,应用L交互的,总要让用戯入数据吧Q就增加了HTTP Post协议?
HTTP Getl典、简单、有效。可以用丰富的URI定义把这个优势发挥到极致。这个实C比较单、优雅。就不多说了。主要的隄在于HTTP Post。下面的讨论主要应对“HTTP Post”q个复杂现象?br />
HTTP Post从来׃让h们满意。当输入逻辑复杂C定程度,表单数据的繁杂、凌乱、散落,C服务器端很难l织h。输入方面B/Sl构实和C/Sl构难以Ҏ。于是,出现了XMLHttpQ能够把参数在浏览器里面l织成ؓ一个统一的XML数据l构Q或其他格式Q,发送到服务器端Q一ơ解析出来。SOAP做这个方面,更是拿手好戏。所以,很多XMLHttpE序直接采用SOAP作ؓ通信协议。而REST风格的HTTP Post则和HTML Form Post没有太大的本质区别?
REST在HTTP Get斚w更胜一{,SOAP在HTTP Post斚w更胜一{V可以根据Web应用的特点,ҎHTTP Get / HTTP Post 面的比例,选择适合的技术?
我们再进一步分析HTTP Post的数据内宏VHTTP Post的数据,可能包含三种cdQ?
(1) 需要存在服务器的数据
比如Q用h册时候,输入的基本信息,用户名、密码、电子邮件等。这些信息要存放到服务器的数据库?
对于q种基本信息QHTTP PostQXMLHttpQSOAP处理hQ难度都不大Q没有很大区别?
B2B的数据交换,也属于这个类别。用何种技术区别不大。一般采用SOAPQ因为SOAP是一U流行的标准协议?
(2) 服务调用参数
比如Q用戯行复合条件查询的时候,输入的查询条件。这个时候,HTTP Post处理h非常蹩脚。而XMLHttpQSOAP则具有很大的优势。可以把复杂的查询条件很好组l成XML数据Q发送到服务器端l一处理。SOAP里面甚至可以定义对象名、方法名{详l的调用信息?
(3) 指o
q种情况比较见。上面的参数cd中提到的“对象名、方法名{详l的调用信息”Q和q个指ocd有些交叉?
假如一个SOAP调用Ҏ里面的参C是一个自定义的对象,q个自定义对象的属性数据在SOAP信息中进行了定义。到了服务器端之后,服务端程序首先调用这个自定义参数的构造函敎ͼ生成q个参数对象Q然后调用对应的服务对象Q把q个参数传给服务。这个过E可以看作是一个顺序指令:[1]构造参数[2]调用服务?
q只是最单的情况。而目前的Web Service一般也支持到q个E度?
我的看法是,一不做Q而不休。既焉把调用信息定义到q个E度了,不如做的更彻底一些,全面完善的支持指令。这个指令则意味着逻辑。前面讲q了Q我不赞成用XML Tag表示逻辑Q而赞成脚本。这里比较适合的脚本是JavaScriptQ因为JavaScript比较通用Q客L、服务器端都可以解释执行。注意,q里和一般的做法正好相反Q一般的Web应用L把JavaScript从服务器传到览器里面执行,而这里是把JavaScript在浏览器里组l好Q发l服务器端处理;q个JavaScript会在服务器端执行,调用服务器端的对象。D个SOAP含有JavaScript指o的例?(只是C意Q非标准格式) Q?
<soap envelope>
<XML Data>
<a>
<b>12</b>
</a>
<c>
<d>21</d>
</c>
<e>
<e>16</e>
</e>
</XML Data>
<script>
final_result = default;
result1 = service1.service(a.b);
if(result1.ok){
result2 = service2.service(c.d);
if(result2.ok)
final_result = service3.service(e.f);
}
</script>
< /soap envelope >
q个好处是:
[1] 发布了更多的基本Service。给客户提供了更大的灉|度?
比如Q这里就发布?个Service。由用户自己l织逻辑?
按照传统的做法,上述程整个包装在服务器端执行。发布给用户的Service只有最外面的一个ServiceQ而且高度耦合Qif, else, if, else程hard code在服务器端)Q不灉|Q不通用?
q里的方法,可以让客户端随意组lservice1, service2, service3的调用顺序和方式?
[2] 减少了通信ơ数?
假如q段Script在客L执行Q那么和服务器要q行3ơ通信?
传统Web的权限控制一般在URLU别Q这Uscript -> server方式的权限控制则要在对象U别、方法别、Code片断U别了,复杂很多Q也许要大量应用Java的Code权限认证机制?
以上展开讨论?Web Service, HTTP Get/Post。下面我们回到Web框架层?
前面说了QJSPLetl了我很大的启发。很多思\可以借鉴?
当然Q我q不赞成用JSP作Dispatcher, Controller?1) 因ؓJSP要编译成ServletQ而Servlet是Web Server理的比较昂늚资源。一个Webpȝ中JSP辑ֈ几千个,׃遇到性能瓉?2) JSP中的代码重用很成问题。一般只能通过include file的方式?
可以借鉴的思\?1) JSPLet 的入口是JSP文gQ这一步的URL到处理程序的映射是Servlet/JSP Container自然支持的。这是免配置的?2) 丰富的URL参数定义Q良好的对象Ҏd能力?
我开发的开源Web框架lightwebQ将具备如下Ҏ:
(1) 支持两个层次的编E接口?
interface Action { void service(request, response, servletContext); }
q个Action比Struts Action, Spring MVC Controller高一个别。相当于Dispatcher, 相当于JSPLet的JSP控制文g。这个用来做最外层的入口控制?
同时Q也支持单的JavaBean.method的直接调用。相当于WebWork ActionQJSPLet Registered Object。这个用来做具体的事情?
(2) 支持丰富的对象寻址URIQ比如http://my.com/myProject/myModule/myEntry.action?object=calculator&method=add&p1=1&p2=3
q表C通过 myEntry.acionq个入口Q调用caculator.add(1, 2)Ҏ?
如果用URL Rewriter可以化?
http://my.com/myProject/myModule/myEntry/calculator/add/1/3
看v来就很象XLink + XPointer了?
(3) 免配|。或者说极少的配|?
框架Ҏ一定的匚w准则Q把myModule/myEntry.action映射?
com.mycompany.mymodule.MyEntryAction q个cȝserviceҎ?
q个serviceҎ负责Ҏobject, method的名字,L到对应的beanQƈҎ参数q行属性设|验证,q执行对应的bean.method。然后,把这个bean作ؓModel和templatel合Q输出结果?
同样Qtemplate的获取也是根据一定的匚w准则Q根据myModule/myEntry扑ֈ
Mymodule/myentry.html 或者Mymodule/myentry/calculator.html?
q样的lightwebp够同时对应简单和复杂。复杂控制的需求交lAction接口来做Q简单的一般具体Q务交l普通Java Beand?
Web框架层可以做的非常复杂,可以做的非常单。Lightweb的目标,是分成多个单的部分Q各部分合v来就能够完成从非常简单到非常复杂的需求?
接下来,我们来看O/R?
7QO/R
Hibernate, EJB Entity Bean产品QJDO产品QiBatis是比较流行的几种O/R Mapping Framework?
我做的一些工作中Q经常涉及到复杂的优化过的native SQLQƈ且涉及到大量的批量复杂逻辑处理Q现有的O/R框架都不能满_能和性能要求?
我做样一个lightor框架Q思\借鉴了Martin Fowler的《企业架构模式》里面讲q的一些O/R的Row Mapper, Column Mapper{概c?
最l典的用法是Q?
ResultSet rs = ps.executeQuery( a long complex native sql);
//will return a lot of records
A a = new A();
B b = new B();
IMapper aMapper = MapperService.getMapper(A.class);
IMapper bMapper = MapperService.getMapper(B.class);
While(rs.next()){
aMapper.populate(a, rs);
bMapper.populate(b, rs);
businessLogic(a, b);
}
可以看到QLightor不需要一下子把所有纪录都攑ֈ一个Object List里面。完全可以随取随用。整个过E中Qa, b只有一份,极大的节省了I间、时_也极大的提高了开发效率,减少了重复代码?
没有M一个其它O/R能够支持q种用法。这里面Qlightor的mapper的populateҎ需要ResultSet参数。一般的O/R不屑于这么做的,别说ResultSetQ连Connection都想包装h不给你看?
Lightor的设计思\也是同时应对单和复杂。Lightor的Mapper实体部分是自动生成代码。类gJDO的静态Enhance。不同的是,JDO静态Enhance直接修改bean class。而Lightor则不动原有的beanQ只是多生成了对应的Mapper Source/Class。这U方式是最利于跟踪调试的。至于发布部|Ԍ和JDO的情况差不多Q不如Hibernate的动态代码增强?
q里我很慕Python, Ruby{动态解释语a?
q一层我主要x的是性能Q缓存策略等{,而不是简ѝ我觉得Q一个应用系l的瓉主要存在于O/R, DB层。不应该单纯Zq求OOl构的优雅,或者编E的方便Q而牺牲了一些可能优化的地方?
关于Lightor的缓存策? 我的Blog上有几篇文章?
http://blog.csdn.net/buaawhl
数据库对象的~存{略
http://blog.csdn.net/buaawhl/archive/2004/12/21/224184.aspx
分页 & QueryKey & 定长预取
http://blog.csdn.net/buaawhl/archive/2005/01/08/245005.aspx
8Qȝ
我理想中的Web开发架构是q样的:
开发速度快,q行速度快,l构清晰优雅?
具体到每一层?
Web框架层主要追?开发速度快?
O/R层主要追?q行速度快?
面资源层和面模板层主要追?l构清晰优雅?/p>