DWR幫助說明-伺服器端程式的編寫
也許朋友們會以為這是DWR官方釋出的什麼幫助,但非常遺憾這不是。現在不少朋友在使用DWR開發專案,我也是其中之一,但苦於關於DWR的幫助文件實在太少,很多問題都不得不自己去鑽研DWR的原始碼才能解決或理解。經過一段時間的苦苦鑽研,總結出那麼一點點心得,現在從DWR原始碼實現的角度詳細講解DWR的使用,寫出來與大家分享。今天我談一談DWR伺服器端程式碼的編寫。
前面我談到,dwr使我們編寫的程式碼完全省略掉了MVC層,也就是說我們可以從過去需要在MVC層做的form與vo的資料轉換、為每個頁面訪問提供相應的action和一系統複雜的配置都省略掉了,似乎直接就從頁面到bus了。但是,這樣的省略似乎來得太快了點兒,一下子還真不太適應。我最初就有這樣的感覺,其中一些以前應當在action中執行的功能,現在需要另想辦法,最常見的就是獲取request、response、session和許可權校驗。
獲取request、response和session
據說在其它一些ajax的產品中沒有提供對request、response和session的獲取,需要自己寫程式去取得,但在dwr中就完全可以沒有這個顧慮了。在dwr中有一個WebContextFactory類,靜態呼叫這個類的get()方法就可以得到dwr的另一個類:WebContext。在WebContext中,你可以看到getHttpServletRequest()、getHttpServletResponse()、getSession()等方法,通過它們就可以順利地得到request、response和session了。
雖然dwr可以方便快捷地讓我們獲取request、response和session,但另一個問題我覺得值得我們思考:我們應當在哪個層次上獲取它們?我們使用dwr的方便之處是沒有MVC層,也就似乎是說從頁面端直接就到達了bus層。雖然實際並不是這樣,但從頁面到bus之間的工作都是dwr在為我們完成的,我們沒有對這部分編碼。這樣,我們似乎也就可以直接在bus層通過dwr提供的方法直接引用和處理request、response和session好 了。當然可以這樣處理,但我認為這樣做不是一個好的設計,因為這樣做違背“不要跟陌生人說話”原則。眾所周知,“不要跟陌生人說話”是軟體設計模式中一個 重要的原則,它要求我們在設計某個類的過程中,不要去訪問與自己職能不相關的類,以便保持自身功能的獨立性。我們傳統的對bus層其職能的定義,應當是實現某個業務功能。為了實現這個業務功能也許需要一些資料,比如從request獲取資料,從資料庫獲取資料。但是這些資料是如何獲取的,都不是bus層關心的問題。它只在意從自己引數中,或者呼叫某個介面來獲得資料,這就是bus的職能。
如果我們在寫bus的時候加入了通過dwr獲取request、response、session的程式碼,那麼bus就開始與陌生人說話了,也就是做了一些與自己職能無關的工作,訪問了一些不應該訪問的類。這樣做的後果就是,如果今後我們希望將這些bus重用到別的專案中,而這個專案又不使用dwr,或者在本專案中需要重用某個bus到別的功能中,而這個功能不使用dwr,那麼這樣的設計將使這種重用變為不可能。
說了這麼半天虛的,舉一個例子來實際說明一下該怎樣設計。在一個專案中需要使用request、response、session的地方最常用的就是獲取登入使用者的使用者資訊,如他的使用者名稱、所在部門、擁有許可權等。這個功能在各個bus中可能都用得到,而且功能比較固定,因此我們將它抽象出來做成一個公用類。在寫這個公用類前我們先寫一個獲取request、response、session的公用類,具體的寫法如下:
- public class Context {
- private static WebContext getContext(){
- return WebContextFactory.get();
- }
- public static HttpServletRequest getRequest(){
- return getContext().getHttpServletRequest();
- }
- public static HttpServletResponse getResponce(){
- return getContext().getHttpServletResponse();
- }
- public static HttpSession getSession(){
- return getContext().getSession();
- }
- }
然後寫一個UserInfoUtil的公用類,引用Context來獲得session中的使用者資訊,供其它bus呼叫。你也可以引用Context寫出其它類來獲取和操作request、response、session,總之就是不要寫到bus中。
許可權校驗
前面談完了request、response、session的問題,緊跟著我們就來談許可權校驗的問題。在dwr中似乎頁面端可以直接就去訪問bus的各個方法,這從資訊保安的角度講是非常危險的。我們必須對頁面訪問bus進行安全校驗。根據前面的思路,這樣的校驗不應當寫在bus中,而是抽象出來形成公用類。就這個問題我在網上搜尋了一下,有不是網友討論過這個問題,總結一下有2種思路:一種是為dwr設計一個filter,另一種是運用aop為bus設計攔截器。對比這2種思路,我更欣賞後一種思路,因為它更靈活多變,也更適合與spring結合使用。我們再展開分析一下它的優勢所在吧。
首先,我們可能在不同的專案中會對為專案提供多種許可權校驗的機制,比如通過部門級次進行校驗、通過分配給使用者的功能進行校驗、通過使用者的特殊身份(總經理、局長等)進行校驗等。這些校驗機制並不是每個bus都需要使用的,有的bus使用這種機制,有的bus使用那種機制,有的bus同時使用好幾種機制。
另外,我們還可能出現,一些特殊的功能需要單獨為它設計一個許可權校驗機制,這個機制只作用與它自己。
還有一種情況是許可權校驗機制需要分不同的方法進行校驗,如增刪改一個校驗機制,而查詢是另一種校驗機制。
然後,我們不希望在開發過程中加上許可權校驗機制,這無疑會為我們的除錯增加許多的不便。
總結以上所有對許可權校驗的需求,使用filter似乎有些力不從心,而aop卻完全可以勝任。在系統設計完成以後再通過配置來新增系統所需的諸如許可權校驗、事務處理等功能是aop的基本思想。而Aop可以在spring的配置檔案中配置哪些bus使用哪些校驗攔截器,也可以為一個bus配置多個攔截器。Spring提供了通過bean名稱匹配的方式(諸如*Bus、*Service)為所有bus配置攔截器,也可以單獨為某個bus配置攔截器。另外,你還可以採用方法名匹配的方式(諸如create*、update*、delete*)決定哪些方法採用哪些許可權攔截器。看了這些是不是覺得眼熟呀,對,這種方式正好是與spring的事務攔截器是完全一樣的方式進行操作的。
Dwr的事務處理
我在前面的文章中提到,在頁面端dwr提供了dwr.engine.beginBatch()和dwr.engine.endBatch()來進行事務處理。如果你在專案中使用了hibernate,可以在web.xml中新增org.directwebremoting.hibernate.H3SessionAjaxFilter就可以實現hibernate的事務處理了。但我認為這沒有什麼用,因為我們通常在bus層通過spring的事務處理機制就可以完美地完成事務處理了,dwr的事務處理則似乎有些多此一舉。
Dwr的除錯功能
最後我要提到的,就是dwr最重要的,也是dwr提供給我們最好用的一個功能:除錯功能。首先我們要開啟除錯功能,也就是在web.xml中,將DwrServlet的debug引數設定為true,然後在瀏覽器中訪問http://[你的專案地址、埠及其專案名]/dwr,就可以顯示出你在dwr中註冊的所有有效的bus,點選某個bus就可以顯示dwr偵測到的該bus的所有方法。如果這些方法使用到某些類引數或返回值,以及哪些方法被你禁用了,在該頁面中都會提示你。另外,在該頁面中還會提示你,要使用該bus,你應當在頁面中引入哪些js。點選這些js的連結並選擇儲存,你還可以看到dwr為你動態生成的js的內容,特別是那個XxxBus.js的內容。這個除錯功能在網上很多dwr的文章中都詳細介紹過,我就不再累贅了。
Dwr的除錯功能完全改變了我們的程式設計方式,至少我是這樣認為的。它讓我們可以將前臺與後臺的編寫和除錯完全分離。首先,我們先編寫後臺程式,就是哪些bus、dao以及相關的類。在編寫的過程中,我們完全可以不用啟動Tomcat、Weblogic等應用伺服器,而是編寫main函式直接執行,大大提高我們執行除錯的效率。後臺程式編寫完成以後,通過dwr的除錯頁面在應用伺服器確認所有的bus方法在伺服器端正常執行,就可以在完全不用重啟伺服器的情況下直接編寫前端頁面程式。這樣的程式設計方式完全就沒有了過去一遍一遍重啟伺服器的痛苦,怎能不說是一種完全的改變呢?
除此以外,與其它框架一樣,我們在運用dwr開發專案的時候同樣會出現一些錯誤。在這些錯誤中,有的是因為dwr自身的bug所致。如何解決dwr的bug造成的錯誤呢?我將在下一篇文章中討論。
相關文章
- DWR幫助文件-dwr.xml檔案的配置XML
- mysql幫助命令使用說明MySql
- Windows 7z 24.07 (x64) 官方幫助說明Windows
- github copilot如何幫助寫程式碼Github
- 幫助文件:使用VNCServer遠端連線伺服器VNCServer伺服器
- 專案範圍說明書如何編寫?
- 軟體需求規格說明書的編寫指南
- Qt/C++編寫的mqtt除錯助手使用說明QTC++MQ除錯
- 讓企業的幫助文件更容易編寫的解決方案——HelpLook
- 一個工具,據說可以幫助恢復ASprotect 1.05的import table,可惜說明書是俄文的 (105字)Import
- 【公式】網上說的幫助上岸是真的嗎公式
- 編碼從娃娃抓起:12款幫助學習程式碼的遊戲遊戲
- 編譯引數-ObjC的說明編譯OBJ
- 大家說說看過的最有幫助的 Oracle 圖書是什麼 ?Oracle
- MySQL大小寫敏感說明MySql
- 老實說,分支預測,是高手過招的殺手鐧,但是對寫業務程式碼沒啥幫助。
- 蜻蜓安全工作臺程式編排簡要說明
- RHEL 7特性說明(七):編譯程式及工具編譯
- 寫程式碼時,編譯器比你聰明編譯
- 幫幫派線上服務平臺專案說明書
- 如何讓Java編譯器幫你寫程式碼Java編譯
- SQL的幫助SQL
- HP伺服器使用說明伺服器
- 通過手寫檔案伺服器,說說前後端互動伺服器後端
- shell程式設計幫助(轉)程式設計
- Nginx+upstream針對後端伺服器容錯的配置說明Nginx後端伺服器
- 藉助 SublimeLinter 編寫高質量的 JS & CSS 程式碼JSCSS
- 藉助SublimeLinter編寫高質量的JavaScript & CSS程式碼JavaScriptCSS
- 用 Git 幫助寫作者更好地完成工作Git
- Pycharm連線遠端伺服器並編寫、執行python程式碼PyCharm伺服器Python
- 關於支援OPenACC的編譯器說明編譯
- 使用 Async / Await 來編寫簡明的非同步程式碼AI非同步
- 幫助命令
- 請幫助,關於聊天室的伺服器程式一執行,cpu就100%,我是按照書本上寫的.伺服器
- Oracle golden gate程式說明OracleGo
- Oracle 後臺程式 說明Oracle
- 資料庫欄位簡寫說明資料庫
- 非同步決策:幫助遠端團隊走向成功非同步