最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解使用Spring MVC統(tǒng)一異常處理實(shí)戰(zhàn)

 更新時(shí)間:2017年04月07日 14:18:31   作者:ufo2910628  
本篇文章主要介紹了詳解使用Spring MVC統(tǒng)一異常處理實(shí)戰(zhàn),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

1 描述

在J2EE項(xiàng)目的開(kāi)發(fā)中,不管是對(duì)底層的數(shù)據(jù)庫(kù)操作過(guò)程,還是業(yè)務(wù)層的處理過(guò)程,還是控制層的處理過(guò)程,都不可避免會(huì)遇到各種可預(yù)知的、不可預(yù)知的異常需要處理。每個(gè)過(guò)程都單獨(dú)處理異常,系統(tǒng)的代碼耦合度高,工作量大且不好統(tǒng)一,維護(hù)的工作量也很大。

那么,能不能將所有類型的異常處理從各處理過(guò)程解耦出來(lái),這樣既保證了相關(guān)處理過(guò)程的功能較單一,也實(shí)現(xiàn)了異常信息的統(tǒng)一處理和維護(hù)?答案是肯定的。下面將介紹使用Spring MVC統(tǒng)一處理異常的解決和實(shí)現(xiàn)過(guò)程。

2 分析

Spring MVC處理異常有3種方式:

(1)使用Spring MVC提供的簡(jiǎn)單異常處理器SimpleMappingExceptionResolver;

(2)實(shí)現(xiàn)Spring的異常處理接口HandlerExceptionResolver 自定義自己的異常處理器;

(3)使用@ExceptionHandler注解實(shí)現(xiàn)異常處理;

3 實(shí)戰(zhàn)

3.1 引言

為了驗(yàn)證Spring MVC的3種異常處理方式的實(shí)際效果,我們需要開(kāi)發(fā)一個(gè)測(cè)試項(xiàng)目,從Dao層、Service層、Controller層分別拋出不同的異常,然后分別集成3種方式進(jìn)行異常處理,從而比較3種方式的優(yōu)缺點(diǎn)。

3.2 實(shí)戰(zhàn)項(xiàng)目

3.2.1 項(xiàng)目結(jié)構(gòu) 

 

3.2.2 Dao層代碼

@Repository("testDao") 
public class TestDao { 
  public void exception(Integer id) throws Exception { 
    switch(id) { 
    case 1: 
      throw new BusinessException("12", "dao12"); 
    case 2: 
      throw new BusinessException("22", "dao22"); 
    case 3: 
      throw new BusinessException("32", "dao32"); 
    case 4: 
      throw new BusinessException("42", "dao42"); 
    case 5: 
      throw new BusinessException("52", "dao52"); 
    default: 
      throw new ParameterException("Dao Parameter Error"); 
    } 
  } 
} 

3.2.3 Service層代碼

public interface TestService { 
  public void exception(Integer id) throws Exception; 
   
  public void dao(Integer id) throws Exception; 
} 
 
@Service("testService") 
public class TestServiceImpl implements TestService { 
  @Resource 
  private TestDao testDao; 
   
  public void exception(Integer id) throws Exception { 
    switch(id) { 
    case 1: 
      throw new BusinessException("11", "service11"); 
    case 2: 
      throw new BusinessException("21", "service21"); 
    case 3: 
      throw new BusinessException("31", "service31"); 
    case 4: 
      throw new BusinessException("41", "service41"); 
    case 5: 
      throw new BusinessException("51", "service51"); 
    default: 
      throw new ParameterException("Service Parameter Error"); 
    } 
  } 
 
  @Override 
  public void dao(Integer id) throws Exception { 
    testDao.exception(id); 
  } 
} 

3.2.4 Controller層代碼

@Controller 
public class TestController { 
  @Resource 
  private TestService testService; 
   
  @RequestMapping(value = "/controller.do", method = RequestMethod.GET) 
  public void controller(HttpServletResponse response, Integer id) throws Exception { 
    switch(id) { 
    case 1: 
      throw new BusinessException("10", "controller10"); 
    case 2: 
      throw new BusinessException("20", "controller20"); 
    case 3: 
      throw new BusinessException("30", "controller30"); 
    case 4: 
      throw new BusinessException("40", "controller40"); 
    case 5: 
      throw new BusinessException("50", "controller50"); 
    default: 
      throw new ParameterException("Controller Parameter Error"); 
    } 
  } 
   
  @RequestMapping(value = "/service.do", method = RequestMethod.GET) 
  public void service(HttpServletResponse response, Integer id) throws Exception { 
    testService.exception(id); 
  } 
   
  @RequestMapping(value = "/dao.do", method = RequestMethod.GET) 
  public void dao(HttpServletResponse response, Integer id) throws Exception { 
    testService.dao(id); 
  } 
} 

3.2.5 JSP頁(yè)面代碼 

<%@ page contentType="text/html; charset=UTF-8"%> 
<html> 
<head> 
<title>Maven Demo</title> 
</head> 
<body> 
<h1>所有的演示例子</h1> 
<h3>[url=./dao.do?id=1]Dao正常錯(cuò)誤[/url]</h3> 
<h3>[url=./dao.do?id=10]Dao參數(shù)錯(cuò)誤[/url]</h3> 
<h3>[url=./dao.do?id=]Dao未知錯(cuò)誤[/url]</h3> 
 
 
<h3>[url=./service.do?id=1]Service正常錯(cuò)誤[/url]</h3> 
<h3>[url=./service.do?id=10]Service參數(shù)錯(cuò)誤[/url]</h3> 
<h3>[url=./service.do?id=]Service未知錯(cuò)誤[/url]</h3> 
 
 
<h3>[url=./controller.do?id=1]Controller正常錯(cuò)誤[/url]</h3> 
<h3>[url=./controller.do?id=10]Controller參數(shù)錯(cuò)誤[/url]</h3> 
<h3>[url=./controller.do?id=]Controller未知錯(cuò)誤[/url]</h3> 
 
 
<h3>[url=./404.do?id=1]404錯(cuò)誤[/url]</h3> 
</body> 
</html> 

3.3 集成異常處理

3.3.1 使用SimpleMappingExceptionResolver實(shí)現(xiàn)異常處理

1、在Spring的配置文件applicationContext.xml中增加以下內(nèi)容:

<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> 
  <!-- 定義默認(rèn)的異常處理頁(yè)面,當(dāng)該異常類型的注冊(cè)時(shí)使用 --> 
  <property name="defaultErrorView" value="error"></property> 
  <!-- 定義異常處理頁(yè)面用來(lái)獲取異常信息的變量名,默認(rèn)名為exception --> 
  <property name="exceptionAttribute" value="ex"></property> 
  <!-- 定義需要特殊處理的異常,用類名或完全路徑名作為key,異常也頁(yè)名作為值 --> 
  <property name="exceptionMappings"> 
    <props> 
      <prop key="cn.basttg.core.exception.BusinessException">error-business</prop> 
      <prop key="cn.basttg.core.exception.ParameterException">error-parameter</prop> 
 
      <!-- 這里還可以繼續(xù)擴(kuò)展對(duì)不同異常類型的處理 --> 
    </props> 
  </property> 
</bean> 

2、啟動(dòng)測(cè)試項(xiàng)目,經(jīng)驗(yàn)證,Dao層、Service層、Controller層拋出的異常(業(yè)務(wù)異常BusinessException、參數(shù)異常ParameterException和其它的異常Exception)都能準(zhǔn)確顯示定義的異常處理頁(yè)面,達(dá)到了統(tǒng)一異常處理的目標(biāo)。

3、從上面的集成過(guò)程可知,使用SimpleMappingExceptionResolver進(jìn)行異常處理,具有集成簡(jiǎn)單、有良好的擴(kuò)展性、對(duì)已有代碼沒(méi)有入侵性等優(yōu)點(diǎn),但該方法僅能獲取到異常信息,若在出現(xiàn)異常時(shí),對(duì)需要獲取除異常以外的數(shù)據(jù)的情況不適用。

3.3.2 實(shí)現(xiàn)HandlerExceptionResolver 接口自定義異常處理器

1、增加HandlerExceptionResolver 接口的實(shí)現(xiàn)類MyExceptionHandler,代碼如下:

public class MyExceptionHandler implements HandlerExceptionResolver { 
 
  public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, 
      Exception ex) { 
    Map<String, Object> model = new HashMap<String, Object>(); 
    model.put("ex", ex); 
     
    // 根據(jù)不同錯(cuò)誤轉(zhuǎn)向不同頁(yè)面 
    if(ex instanceof BusinessException) { 
      return new ModelAndView("error-business", model); 
    }else if(ex instanceof ParameterException) { 
      return new ModelAndView("error-parameter", model); 
    } else { 
      return new ModelAndView("error", model); 
    } 
  } 
} 

2、在Spring的配置文件applicationContext.xml中增加以下內(nèi)容:

復(fù)制代碼 代碼如下:

<bean id="exceptionHandler" class="cn.basttg.core.exception.MyExceptionHandler"/> 

3、啟動(dòng)測(cè)試項(xiàng)目,經(jīng)驗(yàn)證,Dao層、Service層、Controller層拋出的異常(業(yè)務(wù)異常BusinessException、參數(shù)異常ParameterException和其它的異常Exception)都能準(zhǔn)確顯示定義的異常處理頁(yè)面,達(dá)到了統(tǒng)一異常處理的目標(biāo)。

4、從上面的集成過(guò)程可知,使用實(shí)現(xiàn)HandlerExceptionResolver接口的異常處理器進(jìn)行異常處理,具有集成簡(jiǎn)單、有良好的擴(kuò)展性、對(duì)已有代碼沒(méi)有入侵性等優(yōu)點(diǎn),同時(shí),在異常處理時(shí)能獲取導(dǎo)致出現(xiàn)異常的對(duì)象,有利于提供更詳細(xì)的異常處理信息。

3.3.3 使用@ExceptionHandler注解實(shí)現(xiàn)異常處理

1、增加BaseController類,并在類中使用@ExceptionHandler注解聲明異常處理,代碼如下:

public class BaseController { 
  /** 基于@ExceptionHandler異常處理 */ 
  @ExceptionHandler 
  public String exp(HttpServletRequest request, Exception ex) { 
     
    request.setAttribute("ex", ex); 
     
    // 根據(jù)不同錯(cuò)誤轉(zhuǎn)向不同頁(yè)面 
    if(ex instanceof BusinessException) { 
      return "error-business"; 
    }else if(ex instanceof ParameterException) { 
      return "error-parameter"; 
    } else { 
      return "error"; 
    } 
  } 
} 

2、修改代碼,使所有需要異常處理的Controller都繼承該類,如下所示,修改后的TestController類繼承于BaseController: 

public class TestController extends BaseController 

3、啟動(dòng)測(cè)試項(xiàng)目,經(jīng)驗(yàn)證,Dao層、Service層、Controller層拋出的異常(業(yè)務(wù)異常BusinessException、參數(shù)異常ParameterException和其它的異常Exception)都能準(zhǔn)確顯示定義的異常處理頁(yè)面,達(dá)到了統(tǒng)一異常處理的目標(biāo)。

4、從上面的集成過(guò)程可知,使用@ExceptionHandler注解實(shí)現(xiàn)異常處理,具有集成簡(jiǎn)單、有擴(kuò)展性好(只需要將要異常處理的Controller類繼承于BaseController即可)、不需要附加Spring配置等優(yōu)點(diǎn),但該方法對(duì)已有代碼存在入侵性(需要修改已有代碼,使相關(guān)類繼承于BaseController),在異常處理時(shí)不能獲取除異常以外的數(shù)據(jù)。

3.4 未捕獲異常的處理

對(duì)于Unchecked Exception而言,由于代碼不強(qiáng)制捕獲,往往被忽略,如果運(yùn)行期產(chǎn)生了Unchecked Exception,而代碼中又沒(méi)有進(jìn)行相應(yīng)的捕獲和處理,則我們可能不得不面對(duì)尷尬的404、500……等服務(wù)器內(nèi)部錯(cuò)誤提示頁(yè)面。

我們需要一個(gè)全面而有效的異常處理機(jī)制。目前大多數(shù)服務(wù)器也都支持在Web.xml中通過(guò)<error-page>(Websphere/Weblogic)或者<error-code>(Tomcat)節(jié)點(diǎn)配置特定異常情況的顯示頁(yè)面。修改web.xml文件,增加以下內(nèi)容:

<!-- 出錯(cuò)頁(yè)面定義 --> 
<error-page> 
  <exception-type>java.lang.Throwable</exception-type> 
  <location>/500.jsp</location> 
</error-page> 
<error-page> 
  <error-code>500</error-code> 
  <location>/500.jsp</location> 
</error-page> 
<error-page> 
  <error-code>404</error-code> 
  <location>/404.jsp</location> 
</error-page> 
 
<!-- 這里可繼續(xù)增加服務(wù)器錯(cuò)誤號(hào)的處理及對(duì)應(yīng)顯示的頁(yè)面 --> 

4 解決結(jié)果

1、運(yùn)行測(cè)試項(xiàng)目顯示的首頁(yè),如下圖所示: 

2、業(yè)務(wù)錯(cuò)誤顯示的頁(yè)面,如下圖所示: 

3、參數(shù)錯(cuò)誤顯示的頁(yè)面,如下圖所示: 

4、未知錯(cuò)誤顯示的頁(yè)面,如下圖所示: 

5、服務(wù)器內(nèi)部錯(cuò)誤頁(yè)面,如下圖所示: 

5 總結(jié)

綜合上述可知,Spring MVC集成異常處理3種方式都可以達(dá)到統(tǒng)一異常處理的目標(biāo)。從3種方式的優(yōu)缺點(diǎn)比較,若只需要簡(jiǎn)單的集成異常處理,推薦使用SimpleMappingExceptionResolver即可;若需要集成的異常處理能夠更具個(gè)性化,提供給用戶更詳細(xì)的異常信息,推薦自定義實(shí)現(xiàn)HandlerExceptionResolver接口的方式;若不喜歡Spring配置文件或要實(shí)現(xiàn)“零配置”,且能接受對(duì)原有代碼的適當(dāng)入侵,則建議使用@ExceptionHandler注解方式。

6 源代碼

源代碼項(xiàng)目如下所示,為Maven項(xiàng)目,若需運(yùn)行,請(qǐng)自行獲取相關(guān)的依賴包。

點(diǎn)擊這里獲取源代碼 

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 解決JSONObject.toJSONString()輸出null的問(wèn)題

    解決JSONObject.toJSONString()輸出null的問(wèn)題

    這篇文章主要介紹了解決JSONObject.toJSONString()輸出null的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • JAVA找不到符號(hào)的三種解決方案

    JAVA找不到符號(hào)的三種解決方案

    這篇文章主要給大家介紹了關(guān)于JAVA找不到符號(hào)的三種解決方案, 找不到符號(hào)錯(cuò)誤主要發(fā)生在我們?cè)噲D引用一個(gè)未在我們正在編譯的程序中聲明的變量時(shí),這意味著編譯器不知道我們所引用的Java變量,需要的朋友可以參考下
    2024-03-03
  • SpringBoot淺析緩存機(jī)制之Redis單機(jī)緩存應(yīng)用

    SpringBoot淺析緩存機(jī)制之Redis單機(jī)緩存應(yīng)用

    在上文中我介紹了Spring Boot使用EhCache 2.x來(lái)作為緩存的實(shí)現(xiàn),本文接著介紹使用單機(jī)版的Redis作為緩存的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • SpringBoot中的@PreAuthorize注解詳解

    SpringBoot中的@PreAuthorize注解詳解

    這篇文章主要介紹了SpringBoot中的@PreAuthorize注解詳解,@PreAuthorize注解會(huì)在方法執(zhí)行前進(jìn)行權(quán)限驗(yàn)證,支持Spring?EL表達(dá)式,它是基于方法注解的權(quán)限解決方案,需要的朋友可以參考下
    2023-09-09
  • Java枚舉的使用與反射應(yīng)用方式

    Java枚舉的使用與反射應(yīng)用方式

    枚舉類型是一種特殊的類,限定為固定實(shí)例集合,且是類型安全和線程安全的,枚舉類型不可繼承,但可以添加屬性和方法,支持單例模式,枚舉常量可以通過(guò)反射獲取和操作,提供了靈活性和擴(kuò)展性
    2024-09-09
  • Java獲取兩個(gè)字符串中最大相同子串的方法

    Java獲取兩個(gè)字符串中最大相同子串的方法

    今天小編就為大家分享一篇Java獲取兩個(gè)字符串中最大相同子串的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-07-07
  • 一文詳解Spring如何控制Bean注入的順序

    一文詳解Spring如何控制Bean注入的順序

    這篇文章主要為大家詳細(xì)介紹Spring如何控制Bean注入的順序,其中續(xù)注意的是在Bean上加@Order(xxx)是無(wú)法控制bean注入的順序的,需要的可以參考一下
    2022-06-06
  • Hibernate分頁(yè)的兩種實(shí)現(xiàn)方法

    Hibernate分頁(yè)的兩種實(shí)現(xiàn)方法

    這篇文章主要介紹了Hibernate分頁(yè)的兩種實(shí)現(xiàn)方法,結(jié)合實(shí)例形式講述了criteria分頁(yè)與hql分頁(yè)的實(shí)現(xiàn)方法,需要的朋友可以參考下
    2016-03-03
  • java中String、StringBuffer與StringBuilder的區(qū)別

    java中String、StringBuffer與StringBuilder的區(qū)別

    這篇文章主要介紹了java 中String和StringBuffer與StringBuilder的區(qū)別,在開(kāi)發(fā)過(guò)程中經(jīng)常會(huì)用到String這個(gè)類進(jìn)行操作。需要的朋友可以收藏下,方便下次瀏覽觀看
    2021-12-12
  • SpringMVC結(jié)合模板模式實(shí)現(xiàn)MyBatisPlus傳遞嵌套JSON數(shù)據(jù)

    SpringMVC結(jié)合模板模式實(shí)現(xiàn)MyBatisPlus傳遞嵌套JSON數(shù)據(jù)

    我們經(jīng)常會(huì)遇到需要傳遞對(duì)象的場(chǎng)景,有時(shí)候,我們需要將一個(gè)對(duì)象的數(shù)據(jù)傳遞給另一個(gè)對(duì)象進(jìn)行處理,但是又不希望直接暴露對(duì)象的內(nèi)部結(jié)構(gòu)和實(shí)現(xiàn)細(xì)節(jié),所以本文給大家介紹了SpringMVC結(jié)合模板模式實(shí)現(xiàn)MyBatisPlus傳遞嵌套JSON數(shù)據(jù),需要的朋友可以參考下
    2024-03-03

最新評(píng)論

恩施市| 敖汉旗| 新邵县| 黄龙县| 晋州市| 香格里拉县| 宣汉县| 平邑县| 浦县| 琼结县| 兰坪| 阜城县| 连城县| 定襄县| 锦州市| 新蔡县| 林口县| 海盐县| 通化市| 浑源县| 页游| 台东县| 屏东县| 确山县| 香河县| 方正县| 故城县| 柘城县| 兴城市| 祁阳县| 桂阳县| 益阳市| 洪泽县| 南通市| 吴桥县| 莲花县| 沙河市| 湘潭县| 永清县| 邵阳市| 平安县|