SpringMVC 異常處理

一、異常解析器應該具有的功能:

1、既然使用異常解析器,那麼就不必在Controller中對異常進行處理,拋出即可,簡化開發,異常統一控制。

2ajax請求(有@ResponseBodyController)發生錯誤,輸出JSON

3、頁面請求(無@ResponseBodyController)發生錯誤,輸出錯誤頁面。

4、 它需要與AnnotationMethodHandlerAdapter使用同一個messageConverters

5、異常處理細節可控制。

二、SpringMVC異常機制總體思想:

1普通頁面出錯後可以跳到統一的錯誤處理頁面,但是ajax就不行了,ajax的本意就是不讓當前頁面發生跳轉,僅局部刷新,從而改善用戶體驗,基本思路是:把異常轉換成json數據返回,這樣ajax的回調函數,就能解析出錯誤原因。(對於僅僅提供json接口發生異常,可以輸出異常json信息

2)普通界面與json數據出錯跳入錯誤界面,需要重寫異常解析器。

3單地統一配置異常,使得發生普通錯誤指定到固定的頁面,ajax發生錯直接通過js獲取,展現給用戶

 

  三、SpringMVC框架中常用的異常處理辦法:

1

Dao層:直接拋出異常即可

Service層:直接拋出異常即可

Controller訪問頁面時出現異常即可跳入錯誤頁面

Ajax請求:出現異常時提醒異常,不跳出界面

2)在項目中Controller中的異常配置:

Web.xml:

<error-page>

        <exception-type>java.lang.Throwable</exception-type>

        <location>/error.html</location>

    </error-page>

    <error-page>

        <error-code>500</error-code>

        <location>/500.html</location>

    </error-page>

    <error-page>

        <error-code>404</error-code>

        <location>/404.html</location>

   </error-page>

 

 

Spring-servlet.xml:

<!-- 覆蓋org.springframework.web.servlet.handler.SimpleMappingExceptionResolver,實現普通請求和ajax請求的異常處理 -->

       <bean id="exceptionResolver" class="xyt.first.web.exception.CustomSimpleMappingExceptionResolver">

              <!-- 異常信息變量名

        配置異常的屬性值爲ex,那麼在錯誤頁面中可以通過 ${ex} 來獲取異常的信息

        如果不配置這個屬性,它的默認值爲exception-->

              <property name="exceptionAttribute" value="ex"></property>

              <!--需要做特殊處理的異常,用類名或者完全路徑作爲key,異常頁面作爲值  -->

              <property name="exceptionMappings">

                     <props>

                       <!-- 表示當拋出NumberFormatException異常時,會跳入commons/number界面 -->

                            <prop key="NumberFormatException">commons/number</prop>

                            <prop key="NullPointerException">commons/null</prop>

                            <prop key="java.lang.ArrayIndexOutOfBoundsException">commons/error</prop>

                     </props>

              </property>

              <!-- 定義發生異常時 視圖與返回碼對應關係 -->

              <property name="statusCodes">

                     <props>

                            <!-- 表示在發生NumberFormatException時返回視圖number,然後這裏定義發生異常時視圖number對應的HttpServletResponse的返回碼是500 -->

                            <prop key="commons/number">500</prop>

                            <prop key="commons/null">503</prop>

                     </props>

              </property>

               <!-- 設置日誌輸出級別,不定義則默認不輸出警告等錯誤日誌信息 -->     

          <property name="warnLogCategory" value="WARN"></property>   

              <!-- 發生異常時默認返回碼404 -->

              <property name="defaultStatusCode" value="500"/>

          <!-- 表示拋出異常時沒有在exceptionMappings找到對應的異常時返回error視圖  -->

              <property name="defaultErrorView" value="commons/error"/>

       </bean>

 

實現普通異常和ajax異常的處理

觀察SimpleMappingExceptionResolver,我們可以複寫其doResolveException(HttpServletRequest request,
            HttpServletResponse response, Object handler, Exception ex)方法,通過修改該方法實現普通異常和ajax異常的處理,代碼如下:

 

 

 

 public class CustomSimpleMappingExceptionResolver extends

SimpleMappingExceptionResolver {

@Override

    protected ModelAndView doResolveException(HttpServletRequest request,  

            HttpServletResponse response, Object handler, Exception ex) {  

        // Expose ModelAndView for chosen error view. 

    

        String viewName = determineViewName(ex, request);  

        if (viewName != null) {// JSP格式返回  

            if (!(request.getHeader("accept").indexOf("application/json") > -1 || (request  

                    .getHeader("X-Requested-With")!= null && request  

                    .getHeader("X-Requested-With").indexOf("XMLHttpRequest") > -1))) {  

                // 如果不是異步請求  

                Integer statusCode = determineStatusCode(request, viewName);  

                if (statusCode != null) {  

                    applyStatusCodeIfPossible(request, response, statusCode);  

                }  

                return getModelAndView(viewName, ex, request);  

            } else {// JSON格式返回  

                try {  

                    PrintWriter writer = response.getWriter();  

                    writer.write(ex.getMessage());  

                    writer.flush();  

                } catch (IOException e) {  

                    e.printStackTrace();  

                }  

                return null;  

  

            }  

        } else {  

            return null;  

        }  

    }   

 

 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章