Terry.Li-彬

          虛其心,可解天下之問(wèn);專其心,可治天下之學(xué);靜其心,可悟天下之理;恒其心,可成天下之業(yè)。

            BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            143 隨筆 :: 344 文章 :: 130 評(píng)論 :: 0 Trackbacks
          <2025年5月>
          27282930123
          45678910
          11121314151617
          18192021222324
          25262728293031
          1234567

          常用鏈接

          留言簿(19)

          隨筆分類(107)

          隨筆檔案(141)

          文章分類(284)

          文章檔案(342)

          相冊(cè)

          收藏夾(58)

          家裝

          最新隨筆

          搜索

          積分與排名

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          Spring3.0之前大家集成GWT基本上都是用 GWT- Widget/Server Library ,現(xiàn)在最新的Spring發(fā)布包提供了REST支持,使用這種方式更自然。其實(shí)這是一個(gè)老外的博客上提出來(lái) 的:http://bigohno.blogspot.com/2009/04/gwt-spring-mvc-and-rest-on-google- app.html

          只是這位同志哥只提出了一個(gè)概念和其中使用到的一些技術(shù),但是沒(méi)有細(xì)節(jié)和代碼,我?guī)缀趸私鼉芍艿臅r(shí)間才把一個(gè)完整的業(yè)務(wù)流程順利跑通。當(dāng)然這也是由于我是第一次使用Gwt1.6,Spring MVC,REST,JSONlib,Restlet,Maven。

          也 許你們注意到了,除了后臺(tái)的openCRX/MDX是我研究多年的技術(shù),其他技術(shù)除了spring,幾乎都是完全沒(méi)有接觸過(guò)。然而,也因?yàn)檫@樣,當(dāng)我完成 了整個(gè)框架基本功能的調(diào)試運(yùn)行之后,得出的結(jié)論是:其他技術(shù)可以不用,Maven2一定要用,Gwt可以不用,SpringMVC/REST一定要用。

          當(dāng)然了,很多只使用過(guò)Ant的同志,對(duì)于Maven可能覺(jué)得可有可無(wú),夠用就好。但是,Maven絕不僅僅是構(gòu)建,而是幫你管理了整個(gè)項(xiàng)目的外部資源、內(nèi)部構(gòu)建和單元測(cè)試的自動(dòng)化過(guò)程。可以這樣說(shuō),一旦用過(guò)Maven,你就再也不愿意去做沒(méi)有Maven的項(xiàng)目。

          SpringMVC是一個(gè)較早出現(xiàn)的技術(shù),以前大家習(xí)慣使用Struts1或者2作為MVC的實(shí)現(xiàn)框架,Spring技術(shù)與之相比并沒(méi)有太大的優(yōu)勢(shì),所以很多人沒(méi)有用過(guò)SpringMVC包括很多老革命在內(nèi)。在最新的Spring3.0M2中已經(jīng)加入了REST,這使得我第一次體驗(yàn)到了AnnotationViewResolver的強(qiáng)大,當(dāng)然最關(guān)鍵的起因在于REST本身就是一個(gè)非常吸引人的技術(shù)框架。而Rest的出現(xiàn),個(gè)人認(rèn)為是來(lái)自于對(duì)Ajax框架最好的支持。

          前面是宣傳一下新技術(shù),下面先給大伙兒上張系統(tǒng)架構(gòu)圖:


          對(duì) 于使用其他后臺(tái)程序的項(xiàng)目,可以簡(jiǎn)單的用自己的Service替換openCRX API。說(shuō)到這里,如果使用Maven進(jìn)行以來(lái)管理和打包,那么會(huì)有一個(gè)很直接的好處,就是GWT的幾個(gè)包,不需要手工編寫(xiě)腳本來(lái)區(qū)分開(kāi)發(fā)時(shí)使用和部署時(shí) 使用,而是簡(jiǎn)單的配置一下scope屬性就可以了。另外需要更新spring最新版本的jar包時(shí),也不需要手工去下載更新,只是簡(jiǎn)單的修改一下版本號(hào)就 可以了。
          特別要說(shuō)的是:當(dāng)使用SpringAOP特性的時(shí)候,需要一個(gè)cglib2的包,當(dāng)我自己從網(wǎng)上搜索時(shí)下載的包死活無(wú)法正常運(yùn)行,而我簡(jiǎn) 單的加入了SpringAOP自己的pom中所使用的依賴之后,就很順利的啟動(dòng)了。這讓我不禁暢想,如果所有的項(xiàng)目都使用maven發(fā)布自己的庫(kù),那是多 美妙的事情呀。
          很遺憾,opencrx/mdx就沒(méi)有一個(gè)自己的maven repository——還好我在網(wǎng)上偶然發(fā)現(xiàn)一篇博客介紹一款maven repository代理軟件,這下可好了,對(duì)于一個(gè)項(xiàng)目組的成員或者整個(gè)公司來(lái)說(shuō),都可以搭建這樣一個(gè)本地庫(kù),就可以“一次導(dǎo)入,到處更新”了,哈 哈。。。
          到這里,相信大家對(duì)于這個(gè)“最新技術(shù)”所組成的“最新框架”應(yīng)該有一個(gè)大致的印象了,下次介紹如何建立一個(gè)基于maven 的GWT1.6+Spring3.0的Eclipse工程。


          這次就是關(guān)于如何 使用Maven2快速搭建一個(gè)支持GWT1.6和Spring3.0的Eclipse工程,這可以幫助我們用最快的速度開(kāi)始真正的開(kāi)發(fā)。

          1.這里,Maven for Google Appengine Java,是一篇介紹如何基于Maven搭建基于google appengine的工程,我們可以利用它先建好一個(gè)gwt的工程,照著圖文教程一步步做,之后就會(huì)得到一個(gè)標(biāo)準(zhǔn)的maven工程。

          2. 執(zhí)行mvn eclipse:eclipse,這樣可以生成eclipse所需要的工程文件和classpath.這里要注意:如果你不需要支持google appengine那么就需要修改pom.xml文件中,把有關(guān)appengine的三個(gè)dependency注釋掉,并且工程目錄下的 build.xml也是可以刪除的

          3.仍然是修改pom.xml文件,加入對(duì)于spring3.0的依賴。這里要注意兩點(diǎn):一、前面提到 的那篇博客里面所說(shuō)的加入一個(gè)dependency來(lái)加入spring3.0的支持,似乎已經(jīng)過(guò)時(shí)了,結(jié)果是一個(gè)包都加不進(jìn)來(lái)。我在網(wǎng)上搜索過(guò)很多有關(guān) spring3.0 maven的文章,最后只有一個(gè)spring官方論壇中的帖子是有效的,但是連接已經(jīng)找不到了,我就直接貼出這一段dependency了:
          <dependency>
          ??? ??? ??? <groupId>asm</groupId>
          ??? ??? ??? <artifactId>asm-commons</artifactId>
          ??? ??? ??? <version>2.2.3</version>
          ??? ??? </dependency>
          ??? ??? <dependency>
          ??? ??? ??? <groupId>asm</groupId>
          ??? ??? ??? <artifactId>asm</artifactId>
          ??? ??? ??? <version>2.2.3</version>
          ??? ??? </dependency>
          ??? ??? <dependency>
          ??? ??? ??? <groupId>org.springframework</groupId>
          ??? ??? ??? <artifactId>org.springframework.core</artifactId>
          ??? ??? ??? <version>${spring.version}</version>
          ??? ??? </dependency>
          ??? ??? <dependency>
          ??? ??? ??? <groupId>org.springframework</groupId>
          ??? ??? ??? <artifactId>org.springframework.web</artifactId>
          ??? ??? ??? <version>${spring.version}</version>
          ??? ??? </dependency>
          ??? ??? <dependency>
          ??? ??? ??? <groupId>org.springframework</groupId>
          ??? ??? ??? <artifactId>org.springframework.transaction</artifactId>
          ??? ??? ??? <version>${spring.version}</version>
          ??? ??? </dependency>
          ??? ??? <dependency>
          ??? ??? ??? <groupId>org.springframework</groupId>
          ??? ??? ??? <artifactId>org.springframework.orm</artifactId>
          ??? ??? ??? <version>${spring.version}</version>
          ??? ??? </dependency>
          ??? ??? <dependency>
          ??? ??? ??? <groupId>org.springframework</groupId>
          ??? ??? ??? <artifactId>org.springframework.jdbc</artifactId>
          ??? ??? ??? <version>${spring.version}</version>
          ??? ??? </dependency>
          ??? ??? <dependency>
          ??? ??? ??? <groupId>org.springframework</groupId>
          ??? ??? ??? <artifactId>org.springframework.web.servlet</artifactId>
          ??? ??? ??? <version>${spring.version}</version>
          ??? ??? </dependency>
          ??? ??? <dependency>
          ??? ??? ??? <groupId>org.springframework</groupId>
          ??? ??? ??? <artifactId>org.springframework.context</artifactId>
          ??? ??? ??? <version>${spring.version}</version>
          ??? ??? </dependency>
          ??? ??? <dependency>
          ??? ??? ??? <groupId>org.springframework</groupId>
          ??? ??? ??? <artifactId>org.springframework.aop</artifactId>
          ??? ??? ??? <version>${spring.version}</version>
          ??? ??? </dependency>
          ??? ??? <dependency>
          ??? ??? ??? <groupId>org.springframework</groupId>
          ??? ??? ??? <artifactId>org.springframework.expression</artifactId>
          ??? ??? ??? <version>${spring.version}</version>
          ??? ??? </dependency>
          ??? ??? <dependency>
          ??? ??? ??? <groupId>org.springframework</groupId>
          ??? ??? ??? <artifactId>org.springframework.test</artifactId>
          ??? ??? ??? <version>${spring.version}</version>
          ??? ??? </dependency>
          ??? ??? <dependency>
          ??? ??? ??? <groupId>org.springframework.webflow</groupId>
          ??? ??? ??? <artifactId>org.springframework.js</artifactId>
          ??? ??? ??? <version>${webflow.version}</version>
          ??? ??? </dependency>
          <dependency>
          ??? ??? ??? <groupId>net.sourceforge.cglib</groupId>
          ??? ??? ??? <artifactId>com.springsource.net.sf.cglib</artifactId>
          ??? ??? ??? <version>2.1.3</version>
          ??? ??? </dependency>
          注 意:asm和cglib都是spring的依賴包,但有于是可選,所以不能在默認(rèn)情況下加進(jìn)工程庫(kù)中。本來(lái)也可以修改相應(yīng)的spring dependency條目,但是我在公司機(jī)器上沒(méi)有maven pom編輯器,就偷一下懶,直接引用了。大家記得,有條件一定要裝一個(gè)maven eclipse的插件,特別是pom編輯器的插件,能夠極大提高生產(chǎn)力。

          4.加入restlet和jsonlib的dependency條目,這兩個(gè)都可以在網(wǎng)上找到,但是要注意一點(diǎn):因?yàn)樗麄儠?huì)依賴spring2.5.6的包,這會(huì)和我們現(xiàn)在的spring3.0沖突,所以需要加入一個(gè)exclusion條目

          5.加入opencrx/mdx依賴,但是實(shí)際上opencrx/mdx開(kāi)發(fā)小組沉迷于cvs/ant之中,給我的答復(fù)是:現(xiàn)狀很好,無(wú)須改變。沒(méi)辦法只好自食其力了.
          首先,自行定義opencrx/mdx的groupId,artifactId,下面可以參考:
          <dependency>
          ??? ??? ??? <groupId>opencrx</groupId>
          ??? ??? ??? <artifactId>opencrx-application</artifactId>
          ??? ??? ??? <version>2.4.1</version>
          ??? ??? ??? <scope>provided</scope>
          ??? ??? </dependency>
          ??? ??? <dependency>
          ??? ??? ??? <groupId>opencrx</groupId>
          ??? ??? ??? <artifactId>opencrx-base</artifactId>
          ??? ??? ??? <version>2.4.1</version>
          ??? ??? ??? <scope>provided</scope>
          ??? ??? </dependency>
          ??? ??? <dependency>
          ??? ??? ??? <groupId>opencrx</groupId>
          ??? ??? ??? <artifactId>opencrx-extension</artifactId>
          ??? ??? ??? <version>2.4.1</version>
          ??? ??? ??? <scope>provided</scope>
          ??? ??? </dependency>
          ??? ??? <dependency>
          ??? ??? ??? <groupId>opencrx</groupId>
          ??? ??? ??? <artifactId>opencrx-kernel</artifactId>
          ??? ??? ??? <version>2.4.1</version>
          ??? ??? ??? <scope>provided</scope>
          ??? ??? </dependency>
          ??? ??? <dependency>
          ??? ??? ??? <groupId>opencrx</groupId>
          ??? ??? ??? <artifactId>opencrx-mail</artifactId>
          ??? ??? ??? <version>2.4.1</version>
          ??? ??? ??? <scope>provided</scope>
          ??? ??? </dependency>
          ??? ??? <dependency>
          ??? ??? ??? <groupId>opencrx</groupId>
          ??? ??? ??? <artifactId>opencrx-security</artifactId>
          ??? ??? ??? <version>2.4.1</version>
          ??? ??? ??? <scope>provided</scope>
          ??? ??? </dependency>
          ??? ??? <dependency>
          ??? ??? ??? <groupId>openmdx.core</groupId>
          ??? ??? ??? <artifactId>openmdx-application</artifactId>
          ??? ??? ??? <version>2.4.1</version>
          ??? ??? ??? <scope>provided</scope>
          ??? ??? </dependency>
          ??? ??? <dependency>
          ??? ??? ??? <groupId>openmdx.core</groupId>
          ??? ??? ??? <artifactId>openmdx-base</artifactId>
          ??? ??? ??? <version>2.4.1</version>
          ??? ??? ??? <scope>provided</scope>
          ??? ??? </dependency>
          ??? ??? <dependency>
          ??? ??? ??? <groupId>openmdx.core</groupId>
          ??? ??? ??? <artifactId>openmdx-base-ext</artifactId>
          ??? ??? ??? <version>2.4.1</version>
          ??? ??? ??? <scope>provided</scope>
          ??? ??? </dependency>
          ??? ??? <dependency>
          ??? ??? ??? <groupId>openmdx.core</groupId>
          ??? ??? ??? <artifactId>openmdx-system</artifactId>
          ??? ??? ??? <version>2.4.1</version>
          ??? ??? ??? <scope>provided</scope>
          ??? ??? </dependency>
          ??? ??? <dependency>
          ??? ??? ??? <groupId>openmdx.core</groupId>
          ??? ??? ??? <artifactId>tomcat-juli</artifactId>
          ??? ??? ??? <version>2.4.1</version>
          ??? ??? ??? <scope>provided</scope>
          ??? ??? </dependency>
          ??? ??? <dependency>
          ??? ??? ??? <groupId>openmdx.portal</groupId>
          ??? ??? ??? <artifactId>openmdx-portal</artifactId>
          ??? ??? ??? <version>2.4.1</version>
          ??? ??? ??? <scope>provided</scope>
          ??? ??? </dependency>
          ??? ??? <dependency>
          ??? ??? ??? <groupId>openmdx.security</groupId>
          ??? ??? ??? <artifactId>openmdx-ldap</artifactId>
          ??? ??? ??? <version>2.4.1</version>
          ??? ??? ??? <scope>provided</scope>
          ??? ??? </dependency>
          ??? ??? <dependency>
          ??? ??? ??? <groupId>openmdx.security</groupId>
          ??? ??? ??? <artifactId>openmdx-radius</artifactId>
          ??? ??? ??? <version>2.4.1</version>
          ??? ??? ??? <scope>provided</scope>
          ??? ??? </dependency>
          ??? ??? <dependency>
          ??? ??? ??? <groupId>openmdx.security</groupId>
          ??? ??? ??? <artifactId>openmdx-security</artifactId>
          ??? ??? ??? <version>2.4.1</version>
          ??? ??? ??? <scope>provided</scope>
          ??? ??? </dependency>
          其次,手工安裝相應(yīng)的jar包到maven repository。這里有一個(gè)可選項(xiàng),就是在本地網(wǎng)上安裝maven repository代理服務(wù)器,那么可以統(tǒng)一安裝在這臺(tái)服務(wù)器上,所有開(kāi)發(fā)人員可以從這里統(tǒng)一更新所有的開(kāi)發(fā)用jar包。

          6. 以上整個(gè)過(guò)程中,如果你是在eclipse環(huán)境中,并且安裝了maven-elcipse插件,那么每次修改了pom.xml文件,都會(huì)自動(dòng)進(jìn)行 maven upate,這樣會(huì)驗(yàn)證其中所有的依賴包的有效性。如果沒(méi)有問(wèn)題,那么可以執(zhí)行:mvn install,把整個(gè)工程構(gòu)建并打包到本地maven repository之中。因?yàn)楸救藢?duì)于Maven研究還不深入,所以把部署的任務(wù)也放到了install之中執(zhí)行。理論上說(shuō),可以增加maven build的run命令在eclipse里面,這樣可以更方便。大家如果有知道這個(gè)方法的,請(qǐng)告知。

          最后總結(jié)一下:如果你對(duì)maven有 更深的了解,就會(huì)發(fā)現(xiàn)更多的驚喜。同樣限于時(shí)間,我還沒(méi)有加入編譯gwt的任務(wù)到pom中,簡(jiǎn)單嘗試下,可以進(jìn)行編譯但是不能生成靜態(tài)頁(yè)面到我指定的目 錄,等有時(shí)間再加上這個(gè)吧,這樣就可以整合gwt compile和deploy into tomcat的任務(wù)了。另外,順便對(duì)比一下maven和ant的build,在maven下一旦包安裝好整個(gè)過(guò)程不超過(guò)10s.但是如果沒(méi)有注釋掉 appengine就會(huì)耗費(fèi)2分鐘以上,我也沒(méi)去研究這到底是什么原因,大家可以自己研究看看,相信其中可以發(fā)現(xiàn)更多的功能和收獲更多的開(kāi)發(fā)樂(lè)趣。


          第一篇中,有一張整個(gè)架構(gòu)的示意圖,其中聯(lián)系前臺(tái)和后臺(tái)的是http/Rest標(biāo)準(zhǔn)協(xié)議。現(xiàn)在我們就先從前臺(tái)所使用的技術(shù)GWT和Restlet開(kāi)始。

          1.GWT 作為一種基于java開(kāi)發(fā)Ajax頁(yè)面的技術(shù)框架,真正的發(fā)展是開(kāi)始于1.5版本(支持了大部分java5的特性和庫(kù)),到了1.6又再一次進(jìn)行了大的修 訂。目前來(lái)說(shuō),它的最大優(yōu)勢(shì)就是支持大量開(kāi)源的控件,包括gwt-ext,smartgwt等等,和另外一個(gè)要強(qiáng)調(diào)的,所見(jiàn)即所得的編輯器GWT Designer(目前似乎已經(jīng)被更名為window builder),有了這兩點(diǎn),對(duì)于java/j2ee開(kāi)發(fā)人員來(lái)說(shuō)幾乎是接近了C/S時(shí)代RAD的開(kāi)發(fā)效率了。可惜的是,對(duì)于一個(gè)完整的web應(yīng)用來(lái)說(shuō) web ui僅僅是前臺(tái)的一部分,在webservice/rest協(xié)議出現(xiàn)前,前端展現(xiàn)和后臺(tái)程序耦合性達(dá)到了令人發(fā)指的地步。GWT也因此沒(méi)有更大范圍的流行 起來(lái),特別是國(guó)內(nèi),幾乎看不到使用gwt成功的案例。難以設(shè)計(jì)/改變風(fēng)格,不熟悉/適應(yīng)這種開(kāi)發(fā)方式,都是讓人難以接近的原因。

          2.Restlet 本身是一個(gè)完整的Rest實(shí)現(xiàn)框架,包括了前端、后臺(tái)以及和其他技術(shù)的集成模塊,我們?cè)谶@里僅僅使用了和GWT集成的Restlet-GWT模塊,大家有 興趣也可以去restlet官方網(wǎng)站查看其它解決方案。不得不說(shuō),restlet在對(duì)于REST支持的領(lǐng)域上已經(jīng)遠(yuǎn)遠(yuǎn)領(lǐng)先,特別是和GWT的集成上,幾乎 為開(kāi)發(fā)人員周到的考慮到了方方面面的需求,簡(jiǎn)化了GWT遠(yuǎn)程調(diào)用的繁瑣(2個(gè)接口類、一個(gè)實(shí)現(xiàn)類再加上servlet的申明),對(duì)于get/post /put/delete來(lái)說(shuō),都僅僅幾行代碼就可以實(shí)現(xiàn),下面是一個(gè)get方法的例子:
          ?? ? ? ? ? ?public void onClick(Widget sender) {
          ?? ? ? ? ? ? ? ?// Add an AJAX call to the server
          ?? ? ? ? ? ? ? ?final Client client = new Client(Protocol.HTTP);
          ?? ? ? ? ? ? ? ?client.get("http://localhost:8888/ping", new Callback() {
          ?? ? ? ? ? ? ? ? ? ?@Override
          ?? ? ? ? ? ? ? ? ? ?public void onEvent(Request request, Response response) {
          ?? ? ? ? ? ? ? ? ? ? ? ?button.setText(response.getEntity().getText());
          ?? ? ? ? ? ? ? ? ? ?}
          ?? ? ? ? ? ? ? ?});
          ?? ? ? ? ? ? ? ?dialogBox.hide();
          ?? ? ? ? ? ?}

          3.對(duì)于頁(yè)面流程、驗(yàn)證/異常處理以及權(quán)限控制,在GWT框架下,都是一種新的挑戰(zhàn),但是也可以借鑒C/S的開(kāi)發(fā)經(jīng)驗(yàn)。
          基 于角色和頁(yè)面的編號(hào),可以處理功能權(quán)限,基于角色的參數(shù)管理,可以控制相應(yīng)的數(shù)據(jù)權(quán)限,基于opencrx可以提供SaaS的數(shù)據(jù)分區(qū)控制。驗(yàn)證和異常處 理依然可以分成前后臺(tái),分別處理。基于GWT,已經(jīng)簡(jiǎn)化了web flow的處理,但是也同時(shí)綁定了業(yè)務(wù)處理的部分流程,只有通過(guò)盡可能多的重用頁(yè)面組件來(lái)提供工作流程的靈活性。


          服務(wù)器的現(xiàn)在最流行的框架就是Spring了,在Spring3.0 MVC中推出了REST的支持,正好可以和前端GWT+Restlet實(shí)現(xiàn)緊密而又松耦合的集成。
          加 上提供JSONView的JSON-lib和后臺(tái)持久層的opencrx,一個(gè)完整的后臺(tái)框架由Spring+Jsonlib+opencrx來(lái)實(shí)現(xiàn)。其 中所有的service和controller以及opencrxContext對(duì)象都是由spring進(jìn)行管理,但是對(duì)于數(shù)據(jù)庫(kù)事務(wù),由于 opencrx api的使用,需要顯式的在代碼中聲明,這是一個(gè)小小的遺憾,好在所有的業(yè)務(wù)已經(jīng)是對(duì)于Opencrx api的封裝了,所以事務(wù)處理是獨(dú)立且無(wú)需互相引用了。下面是spring配置文件的部分(包括了 jsonview,opencrxContext,controller等等的聲明):
          <!-- Dispatches requests mapped to POJO @Controllers implementations -->
          <bean
          class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />

          <!-- ?gwt handler -->
          <bean name="jsonView" class="com.omdasoft.core.ui.server.view.EISCoreJsonView" />
          <!--
          Maps request paths to @Controller classes; e.g. a path of /person
          looks for a controller named PersonController
          -->
          <bean
          class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
          <property name="order" value="0" />
          </bean>
          <context:component-scan base-package="com.omdasoft.core.ui.server.mvc"
          use-default-filters="false">
          <context:include-filter expression="org.springframework.stereotype.Controller"
          type="annotation" />
          </context:component-scan>
          <!--
          Service beans list
          -->
          <context:property-placeholder location="classpath:common.properties" />
          <bean id="opencrxContext" class="com.omdasoft.core.ui.server.common.OpenCrxContext"
          scope="session">
          <aop:scoped-proxy />
          </bean>
          <bean id="baseService" abstract="true">
          <property name="context" ref="opencrxContext"></property>
          </bean>
          <bean id="userService" class="com.omdasoft.core.ui.server.service.UserService"
          parent="baseService" />
          是 不是覺(jué)得很簡(jiǎn)單?個(gè)人認(rèn)為,一個(gè)好的框架應(yīng)該是越簡(jiǎn)單越好,能夠用最少的步驟完成大多數(shù)業(yè)務(wù)流程,并且在需要的時(shí)候可以擴(kuò)展。一個(gè)試圖包羅萬(wàn)象的框架除了 增加開(kāi)發(fā)人員的學(xué)習(xí)和調(diào)試難度之外,沒(méi)有任何好處。而一個(gè)無(wú)法替換的技術(shù)更是增加了框架擴(kuò)展功能的難度。在我們開(kāi)發(fā)的這個(gè)框架中,除了spring mvc是作為REST服務(wù)的提供者和服務(wù)端的管理容器無(wú)法替換之外,其他部分都可以按照需求更換為其他技術(shù)框架。例如,web層可以換成spring mvc管理的jsp等View,后臺(tái)opencrx api可以更換成hibernate管理的持久層和自行設(shè)計(jì)的數(shù)據(jù)庫(kù),而中間的service(業(yè)務(wù)邏輯部分),幾乎不需要大的修改。這也讓我們更專注于 業(yè)務(wù)邏輯的定義和后臺(tái)API接口的通用化、統(tǒng)一化。
          由于本人對(duì)于Spring ViewResolver認(rèn)識(shí)還不深入,所以在Controller中,方法直接返回了ModelAndView(JsonView),而不是簡(jiǎn)單的String,這也是進(jìn)一步優(yōu)化框架的方向之一。下面是一段用戶注冊(cè)的代碼:
          @RequestMapping(value = "/user", method = RequestMethod.POST)
          public ModelAndView addUser(@ModelAttribute("account") Contact contact) {
          Map model = new HashMap();
          try {
          userService.createContact(contact);

          ?? ? ? ? ? ?model.put(ResultConstant.REDIRECT_SCREEN, contact);
          } catch (ServiceException e) {
          model.put(ResultConstant.ERROR_CODE, "/account/"
          + contact.getId());
          }
          return new ModelAndView("jsonView", model);
          }
          另 外要注意的是,和spring mvc處理異常的方式不同,基于Rest/Json對(duì)象來(lái)處理前臺(tái)請(qǐng)求時(shí),返回值和異常必須統(tǒng)一在一個(gè)類型格式下,這樣才方便前臺(tái)獲取對(duì)應(yīng)的數(shù)據(jù)和異常信 息,而Validation異常可以采用GWT-VL框架的方式來(lái)處理,直接拋出ValidationException異常,然后在GWT中,可以用 GWT-VL的方法來(lái)捕獲這個(gè)異常。


          posted on 2010-12-20 00:01 禮物 閱讀(1595) 評(píng)論(0)  編輯  收藏

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。

          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 麻江县| 乐业县| 湟源县| 丹阳市| 长岛县| 萨嘎县| 永新县| 建昌县| 建平县| 拉孜县| 通河县| 郧西县| 紫金县| 晴隆县| 高台县| 博客| 潞城市| 浦城县| 东丰县| 新沂市| 平遥县| 凉山| 凤翔县| 息烽县| 新野县| 广灵县| 钟山县| 高碑店市| 磐石市| 丰台区| 西乡县| 松原市| 龙口市| 六枝特区| 新邵县| 富平县| 东丽区| 晋中市| 浙江省| 灌云县| 修水县|