qileilove

          blog已經(jīng)轉(zhuǎn)移至github,大家請?jiān)L問 http://qaseven.github.io/

          JAVA WEB框架的錯(cuò)誤體系

           不管是什么程序開發(fā)都可能會(huì)出現(xiàn)各種各樣的異常。可能是程序錯(cuò)誤,也可能是業(yè)務(wù)邏輯錯(cuò)誤。針對這個(gè)各個(gè)開發(fā)人員都有自己的處理方式,不同的風(fēng)格增加了業(yè)務(wù)系統(tǒng)的復(fù)雜度和維護(hù)難度。所以定義好一個(gè)統(tǒng)一的異常處理框架還是需要的。我們開發(fā)框架采用java實(shí)現(xiàn),java中的異常一般分為兩種,檢查異常和運(yùn)行時(shí)異常。檢查異常(checked exception)有可能是程序的業(yè)務(wù)異常,這種異常一般都是開發(fā)人員自定義的、知道什么時(shí)候會(huì)拋出什么異常并進(jìn)行捕捉處理。也可以是系統(tǒng)的異常,不捕捉編譯不會(huì)通過,如  IOException、SQLException、ClassNotFoundException , 這種是必須要捕捉的并且大多都是繼承Exception。 運(yùn)行時(shí)異常一般都是系統(tǒng)拋出來的異常,這種異常不捕捉處理也不會(huì)報(bào)編譯錯(cuò)誤,如NullPointerException,ClassCastException。運(yùn)行異常都是繼承至RuntimeException。不管是檢查異常還是運(yùn)行時(shí)異常都是繼承至Exception。另外還有一種異常是系統(tǒng)錯(cuò)誤Error,這種異常是系統(tǒng)出現(xiàn)了故障拋出來的不能捕捉,如OutOfMemoryError。Exception和Error都是繼承至Throwable。

            了解了java的異常體系后,我們設(shè)計(jì)一下web框架的異常處理格式。在以往EJB時(shí)代的J2ee系統(tǒng),一般是標(biāo)準(zhǔn)的三層架構(gòu):web層、業(yè)務(wù)邏輯層、數(shù)據(jù)訪問層,并且每一層都分別部署在不同的機(jī)器集群中。這樣我們的異常一般分為三個(gè),WebException、BizException、DAOException分別映射到web層、業(yè)務(wù)邏輯層、數(shù)據(jù)訪問層。并且這些異常都要設(shè)計(jì)的串行化可以跨機(jī)器傳遞生成異常鏈。這樣的好處是看到異常鏈知道從哪兒拋出來的錯(cuò)誤,比較清晰明了。

            隨著后面spring的推出,java的開發(fā)越來越輕量級很多時(shí)候一臺服務(wù)器可以同時(shí)部署三層并集群化,架構(gòu)模式也慢慢由充血模式演變?yōu)樨氀J剑僖矝]有了厚重的實(shí)體Bean和有狀態(tài)會(huì)話Bean。針對現(xiàn)在輕量級的框架,異常結(jié)構(gòu)如何設(shè)計(jì)呢?

            先看看我們這個(gè)異常結(jié)構(gòu)需要解決的問題是什么?

            1、規(guī)范大家的異常處理方式。

            2、簡化異常處理。

            3、區(qū)分業(yè)務(wù)異常和系統(tǒng)異常,業(yè)務(wù)異常需要業(yè)務(wù)邏輯支持,系統(tǒng)異常需要記錄log。

            4、友好的異常展示。

            5、異常結(jié)構(gòu)可擴(kuò)展。

            針對這些點(diǎn),我的想法是開發(fā)可以使用三個(gè)類:SDKException、BizException、BizSystemException。SDKException是處理的基礎(chǔ)類,可以在里面封裝一些異常處理的基本函數(shù)。BizException是業(yè)務(wù)邏輯處理異常,一般這類異常是不需要記錄log,只是展示給頁面顯示并提示給用戶。如你的用戶名、密碼為空等錯(cuò)誤。BizSystemException是業(yè)務(wù)系統(tǒng)異常,這類異常一般需要捕捉并記錄log,比如數(shù)據(jù)庫的主鍵沖突、sql語句錯(cuò)誤等。按照三層架構(gòu)的話,我們不可能對每一層都捕捉并且記錄log,會(huì)造成重復(fù)log。可以從DAO層把捕捉到的數(shù)據(jù)庫異常轉(zhuǎn)換為BizSystemException拋出,如果有BizException也拋出。業(yè)務(wù)邏輯層對于BizSystemException、BizException不處理直接拋出。所有處理都在web層進(jìn)行集中處理,如果是BizException,根據(jù)錯(cuò)誤碼和錯(cuò)誤消息顯示給用戶對應(yīng)的頁面和錯(cuò)誤消息。如果是BizSystemException告知用戶系統(tǒng)錯(cuò)誤,并把錯(cuò)誤結(jié)果記入log。如果是其他異常和BizSystemException一致。這樣就減少了異常處理的復(fù)雜度,開發(fā)也不用關(guān)心什么檢查異常,運(yùn)行時(shí)異常。


           如果是ajax請求在做web層時(shí),把返回的jsp變成json格式或者流格式輸出即可,不影響異常框架。如采用struts2結(jié)構(gòu)的代碼:

          public String testAjax()
          {
              try
              {
                   genAjaxDataStr(0, "{}");
              } catch (BizException e)
              {
                   getRequest().setAttribute(this.ERRORMESSAGE, e.getErrorMessage());
                   return this.ERRORJSON;
              } catch (BizSystemException e)
              {
                   getRequest().setAttribute(this.ERRORMESSAGE, this.SYSTEMERROR);
                   return this.ERRORJSON;
              } catch (Exception e)
              {
                   this.errorTrace("test", e.getMessage(), e);
                   getRequest().setAttribute(this.ERRORMESSAGE, this.SYSTEMERROR);
                   return this.ERRORJSON;
              }
              return this.NONE;
          }

            這樣前臺就能根據(jù)我們的異常顯示對應(yīng)的錯(cuò)誤頁面了,并能把系統(tǒng)知道的和未知的異常記入log。

            針對struts2還有個(gè)問題,在開發(fā)模式時(shí),struts2和webwork的異常打印在頁面,我們可以根據(jù)頁面輸出進(jìn)行調(diào)試。一但部署在生產(chǎn)環(huán)境,需要將這個(gè)模式關(guān)閉,log就沒有了。

          <constant name="struts.devMode" value="false" />

            為了記錄一些未知的錯(cuò)誤,需要做以下步驟:

            1、將全局的異常映射頁面從struts2的包定義里去掉。如果不去掉,在webwork不會(huì)拋出異常也就找不到出了什么問題。

            2、擴(kuò)展struts的DispatcherFilter捕捉未知的異常并記錄入log。

          <global-exception-mappings>
              <exception-mapping exception="com.linktong.sdk.biz.exception.BizException"
                          result="checkedException" />
          </global-exception-mappings>

            這樣,基本的異常框架就搭建完成。更進(jìn)一步需要做的是:

            1、分布式全局錯(cuò)誤碼體系,保證所有機(jī)器都共用一套錯(cuò)誤碼。

            2、分布式部署,異常傳遞。可以采用hessian序列化錯(cuò)誤碼的機(jī)制,不用傳輸整個(gè)異常鏈節(jié)省帶寬。

            3、集中l(wèi)ogger服務(wù)處理,所有機(jī)器的log統(tǒng)一發(fā)送到集中服務(wù)器處理。logger框架和log4j也有服務(wù)器的機(jī)制。

            針對web框架、分布式部署、log服務(wù)器再討論:)


          posted on 2013-05-10 09:28 順其自然EVO 閱讀(188) 評論(0)  編輯  收藏


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


          網(wǎng)站導(dǎo)航:
           
          <2013年5月>
          2829301234
          567891011
          12131415161718
          19202122232425
          2627282930311
          2345678

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 丽水市| 扶风县| 永春县| 中江县| 新化县| 莱阳市| 佛教| 泽库县| 孟州市| 于田县| 汶上县| 大洼县| 项城市| 天等县| 白城市| 莱芜市| 安乡县| 乐昌市| 图片| 焉耆| 高雄县| 治县。| 蕉岭县| 吉安市| 临海市| 孙吴县| 石林| 康定县| 仙游县| 红桥区| 西安市| 庆云县| 天津市| 萨嘎县| 冕宁县| 阿拉善左旗| 尉犁县| 楚雄市| 磐石市| 孝义市| 上犹县|