SpringMVC實現統一異常

SpringMVC 提供的異常處理主要有兩種方式,一種是直接實現自己的HandlerExceptionResolver,另一種是使用註解的方式實現一個專門用於處理異常的Controller——ExceptionHandler。前者當發生異常時,頁面會跳到指定的錯誤頁面,後者同樣,只是後者會在每個controller中都需要加入重複的代碼。如何進行簡單地統一配置異常,使得發生普通錯誤指定到固定的頁面,ajax發生錯直接通過js獲取,展現給用戶,變得非常重要。下面先介紹下2種異常處理方式,同時,結合現有的代碼,讓其支持ajax方式,實現spring MVC web系統的異常統一處理。

 

       1、實現自己的HandlerExceptionResolver

       HandlerExceptionResolver是一個接口,springMVC本身已經對其有了一個自身的實現——DefaultExceptionResolver,該解析器只是對其中的一些比較典型的異常進行了攔截處理 。

 

Java代碼  收藏代碼
  1. import javax.servlet.http.HttpServletRequest;  
  2. import javax.servlet.http.HttpServletResponse;  
  3.   
  4. import org.springframework.web.servlet.HandlerExceptionResolver;  
  5. import org.springframework.web.servlet.ModelAndView;  
  6.   
  7. public class ExceptionHandler implements HandlerExceptionResolver {  
  8.   
  9.     @Override  
  10.     public ModelAndView resolveException(HttpServletRequest request,  
  11.             HttpServletResponse response, Object handler, Exception ex) {  
  12.         // TODO Auto-generated method stub  
  13.         return new ModelAndView("exception");  
  14.     }  
  15.   
  16. }  

 

       上述的resolveException的第4個參數表示對哪種類型的異常進行處理,如果想同時對多種異常進行處理,可以把它換成一個異常數組。

定義了這樣一個異常處理器之後就要在applicationContext中定義這樣一個bean對象,如:

Xml代碼  收藏代碼
  1. <bean id="exceptionResolver" class="com.tiantian.xxx.web.handler.ExceptionHandler"/>  

 

        2、使用@ExceptionHandler進行處理

        使用@ExceptionHandler進行處理有一個不好的地方是進行異常處理的方法必須與出錯的方法在同一個Controller裏面,如:

Java代碼  收藏代碼
  1. import org.springframework.stereotype.Controller;  
  2. import org.springframework.web.bind.annotation.ExceptionHandler;  
  3. import org.springframework.web.bind.annotation.RequestMapping;  
  4.   
  5. import com.tiantian.blog.web.servlet.MyException;  
  6.   
  7. @Controller  
  8. public class GlobalController {  
  9.   
  10.       
  11.     /** 
  12.      * 用於處理異常的 
  13.      * @return 
  14.      */  
  15.     @ExceptionHandler({MyException.class})  
  16.     public String exception(MyException e) {  
  17.         System.out.println(e.getMessage());  
  18.         e.printStackTrace();  
  19.         return "exception";  
  20.     }  
  21.       
  22.     @RequestMapping("test")  
  23.     public void test() {  
  24.         throw new MyException("出錯了!");  
  25.     }  
  26.       
  27.       
  28. }  

 

       這裏在頁面上訪問test方法的時候就會報錯,而擁有該test方法的Controller又擁有一個處理該異常的方法,這個時候處理異常的方法就會被調用。當發生異常的時候,上述兩種方式都使用了的時候,第一種方式會將第二種方式覆蓋。

 

        3. 針對SpringMVC框架,修改代碼實現普通異常及ajax異常的全部統一處理解決方案

        關於spring異常框架體系講的非常清楚,Dao層,以及sevcie層異常我們建立如下異常。

Java代碼  收藏代碼
  1. package com.jason.exception;  
  2.   
  3. public class BusinessException extends Exception {  
  4.   
  5.     private static final long serialVersionUID = 1L;  
  6.   
  7.     public BusinessException() {  
  8.         // TODO Auto-generated constructor stub  
  9.     }  
  10.   
  11.     public BusinessException(String message) {  
  12.         super(message);  
  13.         // TODO Auto-generated constructor stub  
  14.     }  
  15.   
  16.     public BusinessException(Throwable cause) {  
  17.         super(cause);  
  18.         // TODO Auto-generated constructor stub  
  19.     }  
  20.   
  21.     public BusinessException(String message, Throwable cause) {  
  22.         super(message, cause);  
  23.         // TODO Auto-generated constructor stub  
  24.     }  
  25.   
  26. }  

 

Java代碼  收藏代碼
  1. package com.jason.exception;  
  2.   
  3. public class SystemException extends RuntimeException {  
  4.   
  5.     private static final long serialVersionUID = 1L;  
  6.   
  7.     public SystemException() {  
  8.         // TODO Auto-generated constructor stub  
  9.     }  
  10.   
  11.     /** 
  12.      * @param message 
  13.      */  
  14.     public SystemException(String message) {  
  15.         super(message);  
  16.         // TODO Auto-generated constructor stub  
  17.     }  
  18.   
  19.     /** 
  20.      * @param cause 
  21.      */  
  22.     public SystemException(Throwable cause) {  
  23.         super(cause);  
  24.         // TODO Auto-generated constructor stub  
  25.     }  
  26.   
  27.     /** 
  28.      * @param message 
  29.      * @param cause 
  30.      */  
  31.     public SystemException(String message, Throwable cause) {  
  32.         super(message, cause);  
  33.         // TODO Auto-generated constructor stub  
  34.     }  
  35.   
  36. }  

 

       在sevice層我們需要將建立的異常拋出,在controller層,我們需要捕捉異常,將其轉換直接拋出,拋出的異常,希望能通過我們自己統一的配置,支持普通頁面和ajax方式的頁面處理,下面就詳細講一下步驟。

      (1) 配置web.xml 文件,將常用的異常進行配置,配置文件如下403,404,405,500頁面都配置好了:

 

Xml代碼  收藏代碼
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">  
  3.   <display-name>SpringJSON</display-name>  
  4.   <context-param>    
  5.         <param-name>webAppRootKey</param-name>    
  6.         <param-value>SpringJSON.webapp.root</param-value>    
  7.    </context-param>   
  8.   <!--******************************** -->  
  9.     <!--*******log4j日誌信息的配置,設置在classpath根目錄下 ,spring中很多代碼使用了不同的日誌接口,  
  10.     既有log4j也有commons-logging,這裏只是強制轉換爲log4j!並且,log4j的配置文件只能放在classpath根路徑。  
  11.     同時,需要通過commons-logging配置將日誌控制權轉交給log4j。同時commons-logging.properties必須放置  
  12.     在classpath根路徑****** -->  
  13.     <!--******************************* -->  
  14.     <context-param>  
  15.         <param-name>log4jConfigLocation</param-name>  
  16.         <param-value>classpath:log4j.xml</param-value>  
  17.     </context-param>  
  18.       
  19.     <!--Spring默認刷新Log4j配置文件的間隔,單位爲millisecond,可以不設置 -->  
  20.     <context-param>  
  21.         <param-name>log4jRefreshInterval</param-name>  
  22.         <param-value>60000</param-value>  
  23.     </context-param>  
  24.   
  25.     <!--******************************** -->  
  26.     <!--*******spring bean的配置******** -->  
  27.     <!--applicationContext.xml用於對應用層面做整體控制。按照分層思想,  
  28.     統領service層,dao層,datasource層,及國際化層-->  
  29.     <!--******************************* -->  
  30.     <context-param>  
  31.         <param-name>contextConfigLocation</param-name>  
  32.         <param-value>classpath:applicationContext.xml</param-value>  
  33.     </context-param>  
  34.       
  35.     <listener>  
  36.         <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>  
  37.     </listener>  
  38.     <listener>  
  39.         <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
  40.     </listener>  
  41.     <listener>  
  42.         <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>  
  43.     </listener>  
  44.     <!--******************************** -->  
  45.     <!--*******字符集 過濾器************ -->  
  46.     <!--******************************* -->  
  47.     <filter>  
  48.         <filter-name>CharacterEncodingFilter</filter-name>  
  49.         <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>  
  50.         <init-param>  
  51.             <param-name>encoding</param-name>  
  52.             <param-value>UTF-8</param-value>  
  53.         </init-param>  
  54.         <init-param>  
  55.             <param-name>forceEncoding</param-name>  
  56.             <param-value>true</param-value>  
  57.         </init-param>  
  58.     </filter>  
  59.     <filter-mapping>  
  60.         <filter-name>CharacterEncodingFilter</filter-name>  
  61.         <url-pattern>/*</url-pattern>  
  62.     </filter-mapping>  
  63.       
  64.     <!-- Spring 分發器,設置MVC配置信息 -->  
  65.     <servlet>  
  66.         <servlet-name>SpringJSON</servlet-name>  
  67.         <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
  68.         <init-param>  
  69.             <param-name>contextConfigLocation</param-name>  
  70.             <param-value>classpath:spring/applicationContext-servlet.xml</param-value>  
  71.         </init-param>  
  72.         <load-on-startup>1</load-on-startup>  
  73.     </servlet>  
  74.     <!--******************************** -->  
  75.     <!--***使用.html後綴,一方面用戶不能通過URL知道我們採用何種服務端技術,  
  76.     同時,可騙過搜索引擎,增加被收錄的概率 。真正的靜態網頁可以用.htm,以避免被框架攔截-->  
  77.     <!--******************************* -->  
  78.     <servlet-mapping>  
  79.         <servlet-name>SpringJSON</servlet-name>  
  80.         <url-pattern>*.html</url-pattern>  
  81.     </servlet-mapping>  
  82.     <welcome-file-list>  
  83.         <welcome-file>index.html</welcome-file>  
  84.     </welcome-file-list>  
  85.     <error-page>  
  86.         <error-code>403</error-code>  
  87.         <location>/WEB-INF/pages/error/403.jsp</location>  
  88.     </error-page>  
  89.     <error-page>  
  90.         <error-code>404</error-code>  
  91.         <location>/WEB-INF/pages/error/404.jsp</location>  
  92.     </error-page>  
  93.     <error-page>  
  94.         <error-code>405</error-code>  
  95.         <location>/WEB-INF/pages/error/405.jsp</location>  
  96.     </error-page>  
  97.     <error-page>  
  98.         <error-code>500</error-code>  
  99.         <location>/WEB-INF/pages/error/500.jsp</location>  
  100.     </error-page>  
  101. </web-app>  

         (2)建立相應的error頁面,其中errorpage.jsp 是業務異常界面。

Html代碼  收藏代碼
  1. <%@ page language="java" import="java.util.*" pageEncoding="UTF-8" isErrorPage="true"%>  
  2. <%@ include file="/common/taglibs.jsp"%>  
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
  4. <html xmlns="http://www.w3.org/1999/xhtml">  
  5. <head>  
  6.     <title>error page</title>  
  7.     <script type="text/javascript">  
  8.         $(function(){  
  9.             $("#center-div").center(true);  
  10.         })  
  11.     </script>  
  12. </head>  
  13. <body style="margin: 0;padding: 0;background-color: #f5f5f5;">  
  14.     <div id="center-div">  
  15.         <table style="height: 100%; width: 600px; text-align: center;">  
  16.             <tr>  
  17.                 <td>  
  18.                 <img width="220" height="393" src="${basePath}/images/common/error.png" style="float: left; padding-right: 20px;" alt="" />  
  19.                     <%= exception.getMessage()%>  
  20.                     <p style="line-height: 12px; color: #666666; font-family: Tahoma, '宋體'; font-size: 12px; text-align: left;">  
  21.                     <a href="javascript:history.go(-1);">返回</a>!!!  
  22.                     </p>  
  23.                 </td>  
  24.             </tr>  
  25.         </table>  
  26.     </div>  
  27. </body>  
  28. </html>  


 errorpage.jsp代碼內容如下:

Html代碼  收藏代碼
  1.   

 

        (3)自定義SimpleMappingExceptionResolver覆蓋spring的SimpleMappingExceptionResolver。關於SimpleMappingExceptionResolver的用法,大家都知道,只需在application-servlet.xml中做如下的配置

Java代碼  收藏代碼
  1. <bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">  
  2.       <property name="exceptionMappings">   
  3.         <props>   
  4.           <prop key="com.jason.exception.SystemException">error/500</prop>   
  5.           <prop key="com.jason.exception.BusinessException">error/errorpage</prop>  
  6.           <prop key="java.lang.exception">error/500</prop>  
  7.             
  8.        </props>   
  9.      </property>   
  10.     </bean>  

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

 

Java代碼  收藏代碼
  1. package com.jason.exception;  
  2.   
  3. import java.io.IOException;  
  4. import java.io.PrintWriter;  
  5.   
  6. import javax.servlet.http.HttpServletRequest;  
  7. import javax.servlet.http.HttpServletResponse;  
  8.   
  9. import org.springframework.web.servlet.ModelAndView;  
  10. import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;  
  11.   
  12. public class CustomSimpleMappingExceptionResolver extends  
  13.         SimpleMappingExceptionResolver {  
  14.   
  15.     @Override  
  16.     protected ModelAndView doResolveException(HttpServletRequest request,  
  17.             HttpServletResponse response, Object handler, Exception ex) {  
  18.         // Expose ModelAndView for chosen error view.  
  19.         String viewName = determineViewName(ex, request);  
  20.         if (viewName != null) {// JSP格式返回  
  21.             if (!(request.getHeader("accept").indexOf("application/json") > -1 || (request  
  22.                     .getHeader("X-Requested-With")!= null && request  
  23.                     .getHeader("X-Requested-With").indexOf("XMLHttpRequest") > -1))) {  
  24.                 // 如果不是異步請求  
  25.                 // Apply HTTP status code for error views, if specified.  
  26.                 // Only apply it if we're processing a top-level request.  
  27.                 Integer statusCode = determineStatusCode(request, viewName);  
  28.                 if (statusCode != null) {  
  29.                     applyStatusCodeIfPossible(request, response, statusCode);  
  30.                 }  
  31.                 return getModelAndView(viewName, ex, request);  
  32.             } else {// JSON格式返回  
  33.                 try {  
  34.                     PrintWriter writer = response.getWriter();  
  35.                     writer.write(ex.getMessage());  
  36.                     writer.flush();  
  37.                 } catch (IOException e) {  
  38.                     e.printStackTrace();  
  39.                 }  
  40.                 return null;  
  41.   
  42.             }  
  43.         } else {  
  44.             return null;  
  45.         }  
  46.     }  
  47. }  

 

          配置application-servelt.xml如下:(代碼是在大的工程中提煉出來的,具體有些東西這裏不做處理)

 

Java代碼  收藏代碼
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.        xmlns:mvc="http://www.springframework.org/schema/mvc"  
  5.        xmlns:p="http://www.springframework.org/schema/p"  
  6.        xmlns:context="http://www.springframework.org/schema/context"  
  7.        xmlns:aop="http://www.springframework.org/schema/aop"  
  8.        xmlns:tx="http://www.springframework.org/schema/tx"  
  9.        xsi:schemaLocation="http://www.springframework.org/schema/beans  
  10.             http://www.springframework.org/schema/beans/spring-beans.xsd  
  11.             http://www.springframework.org/schema/context   
  12.             http://www.springframework.org/schema/context/spring-context.xsd  
  13.             http://www.springframework.org/schema/aop   
  14.             http://www.springframework.org/schema/aop/spring-aop.xsd  
  15.             http://www.springframework.org/schema/tx   
  16.             http://www.springframework.org/schema/tx/spring-tx.xsd  
  17.             http://www.springframework.org/schema/mvc   
  18.             http://www.springframework.org/schema/mvc/spring-mvc.xsd  
  19.             http://www.springframework.org/schema/context   
  20.             http://www.springframework.org/schema/context/spring-context.xsd">  
  21.               
  22.     <!-- 配置靜態資源,直接映射到對應的文件夾,不被DispatcherServlet處理 -->  
  23.     <mvc:resources mapping="/images/**" location="/images/"/>  
  24.     <mvc:resources mapping="/css/**" location="/css/"/>  
  25.     <mvc:resources mapping="/js/**" location="/js/"/>  
  26.     <mvc:resources mapping="/html/**" location="/html/"/>  
  27.     <mvc:resources mapping="/common/**" location="/common/"/>  
  28.       
  29.     <!-- Configures the @Controller programming model -->  
  30.     <mvc:annotation-driven />  
  31.       
  32.     <!--掃描web包,應用Spring的註解-->  
  33.     <context:component-scan base-package="com.jason.web"/>  
  34.       
  35.     <bean id="captchaProducer" name= "captchaProducer" class="com.google.code.kaptcha.impl.DefaultKaptcha">    
  36.         <property name="config">    
  37.             <bean class="com.google.code.kaptcha.util.Config">    
  38.                 <constructor-arg>    
  39.                     <props>    
  40.                         <prop key="kaptcha.image.width">300</prop>  
  41.                         <prop key="kaptcha.image.height">60</prop>  
  42.                         <prop key="kaptcha.textproducer.char.string">0123456789</prop>  
  43.                         <prop key="kaptcha.textproducer.char.length">4</prop>   
  44.                     </props>    
  45.                 </constructor-arg>    
  46.             </bean>    
  47.         </property>    
  48.     </bean>   
  49.     <!--   
  50.     <bean id="captchaProducer" class="com.google.code.kaptcha.impl.DefaultKaptcha">    
  51.         <property name="config">    
  52.             <bean class="com.google.code.kaptcha.util.Config">    
  53.                 <constructor-arg>    
  54.                     <props>    
  55.                         <prop key="kaptcha.border">no</prop>    
  56.                         <prop key="kaptcha.border.color">105,179,90</prop>    
  57.                         <prop key="kaptcha.textproducer.font.color">red</prop>    
  58.                         <prop key="kaptcha.image.width">250</prop>    
  59.                         <prop key="kaptcha.textproducer.font.size">90</prop>    
  60.                         <prop key="kaptcha.image.height">90</prop>    
  61.                         <prop key="kaptcha.session.key">code</prop>    
  62.                         <prop key="kaptcha.textproducer.char.length">4</prop>    
  63.                         <prop key="kaptcha.textproducer.font.names">宋體,楷體,微軟雅黑</prop>    
  64.                     </props>    
  65.                 </constructor-arg>    
  66.             </bean>    
  67.         </property>    
  68.     </bean>  
  69.     -->   
  70.     <!--  
  71.     <bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">  
  72.      -->  
  73.      <bean id="exceptionResolver" class="com.jason.exception.CustomSimpleMappingExceptionResolver">  
  74.       <property name="exceptionMappings">   
  75.         <props>   
  76.           <prop key="com.jason.exception.SystemException">error/500</prop>   
  77.           <prop key="com.jason.exception.BusinessException">error/errorpage</prop>  
  78.           <prop key="java.lang.exception">error/500</prop>  
  79.             
  80.        </props>   
  81.      </property>   
  82.     </bean>  
  83.       
  84.     <!--啓動Spring MVC的註解功能,設置編碼方式,防止亂碼-->  
  85.     <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">  
  86.       <property name="messageConverters">     
  87.          <list>     
  88.              <bean class = "org.springframework.http.converter.StringHttpMessageConverter">     
  89.                 <property name = "supportedMediaTypes">  
  90.                       <list>  
  91.                           <value>text/html;charset=UTF-8</value>     
  92.                      </list>     
  93.                 </property>     
  94.              </bean>     
  95.          </list>     
  96.       </property>   
  97.     </bean>  
  98.     <!--對模型視圖名稱的解析,即在模型視圖名稱添加前後綴InternalResourceViewResolver-->  
  99.     <!--默認的就是JstlView所以這裏就不用配置viewClass -->  
  100.     <bean id="viewResolver"  class="org.springframework.web.servlet.view.InternalResourceViewResolver"   
  101.         p:prefix="/WEB-INF/pages/"   
  102.         p:suffix=".jsp" />  
  103. </beans>  

 

        至此,整個異常體系架構配置成功,當整個工程出現異常時,頁面會根據web.xml跳轉到指定的頁面。當在系統應用中出現普通異常時,根據是系統異常還是應用異常,跳到相應的界面,當ajax異常時,在ajax的error中可直接獲得異常。普通的異常我們都配置好了界面,系統會自動跳轉,主要看一下ajax的方式。

        具體演示如下:在登錄界面建立如下的controller

Java代碼  收藏代碼
  1. package com.jason.web;  
  2.   
  3. import java.io.IOException;  
  4. import java.util.Date;  
  5. import java.util.HashMap;  
  6. import java.util.Map;  
  7.   
  8. import javax.servlet.http.HttpServletRequest;  
  9. import javax.servlet.http.HttpServletResponse;  
  10. import javax.servlet.http.HttpSession;  
  11.   
  12. import org.apache.commons.lang.StringUtils;  
  13. import org.springframework.beans.factory.annotation.Autowired;  
  14. import org.springframework.stereotype.Controller;  
  15. import org.springframework.web.bind.annotation.RequestMapping;  
  16. import org.springframework.web.bind.annotation.ResponseBody;  
  17. import org.springframework.web.servlet.ModelAndView;  
  18.   
  19. import com.jason.domain.User;  
  20. import com.jason.exception.BusinessException;  
  21. import com.jason.service.UserService;  
  22. import com.jason.util.Constants;  
  23. import com.jason.web.dto.LoginCommand;  
  24.   
  25. @Controller  
  26. public class LoginController {  
  27.   
  28.     @Autowired  
  29.     private UserService userService;  
  30.   
  31.     /** 
  32.      * jump into the login page 
  33.      *  
  34.      * @return 
  35.      * @throws BusinessException 
  36.      * @throws 
  37.      * @throws BusinessException 
  38.      */  
  39.     @RequestMapping(value = "/index.html")  
  40.     public String loginPage() throws BusinessException {  
  41.         return Constants.LOGIN_PAGE;  
  42.     }  
  43.   
  44.     /** 
  45.      * get the json object 
  46.      *  
  47.      * @return 
  48.      * @throws Exception 
  49.      */  
  50.     @RequestMapping(value = "/josontest.html")  
  51.     public @ResponseBody  
  52.     Map<String, Object> getjson() throws BusinessException {  
  53.         Map<String, Object> map = new HashMap<String, Object>();  
  54.         try {  
  55.             map.put("content""123");  
  56.             map.put("result"true);  
  57.             map.put("account"1);  
  58.             throw new Exception();  
  59.         } catch (Exception e) {  
  60.             throw new BusinessException("detail of ajax exception information");  
  61.         }  
  62.     }  
  63.   
  64.     /** 
  65.      * login in operation 
  66.      *  
  67.      * @param request 
  68.      * @param loginCommand 
  69.      * @return 
  70.      * @throws IOException 
  71.      */  
  72.     @RequestMapping(value = "/login.html")  
  73.     public ModelAndView loginIn(HttpServletRequest request,  
  74.             HttpServletResponse respone, LoginCommand loginCommand)  
  75.             throws IOException {  
  76.   
  77.         boolean isValidUser = userService.hasMatchUser(  
  78.                 loginCommand.getUserName(), loginCommand.getPassword());  
  79.         boolean isValidateCaptcha = validateCaptcha(request, loginCommand);  
  80.   
  81.         ModelAndView modeview = new ModelAndView(Constants.LOGIN_PAGE);  
  82.   
  83.         if (!isValidUser) {  
  84.             // if have more information,you can put a map to modelView,this use  
  85.             // internalization  
  86.             modeview.addObject("loginError""login.user.error");  
  87.             return modeview;  
  88.         } else if (!isValidateCaptcha) {  
  89.             // if have more information,you can put a map to modelView,this use  
  90.             // internalization  
  91.             modeview.addObject("loginError""login.user.kaptchaError");  
  92.             return modeview;  
  93.         } else {  
  94.             User user = userService.findUserByUserName(loginCommand  
  95.                     .getUserName());  
  96.             user.setLastIp(request.getLocalAddr());  
  97.             user.setLastVisit(new Date());  
  98.   
  99.             userService.loginSuccess(user);  
  100.   
  101.             // we can also use  
  102.             request.getSession().setAttribute(Constants.LOGINED, user);  
  103.             String uri = (String) request.getSession().getAttribute(  
  104.                     Constants.CURRENTPAGE);  
  105.             if (uri != null  
  106.                     && !StringUtils.equalsIgnoreCase(uri,  
  107.                             Constants.CAPTCHA_IMAGE)) {  
  108.                 respone.sendRedirect(request.getContextPath() + uri);  
  109.             }  
  110.             return new ModelAndView(Constants.FRONT_MAIN_PAGE);  
  111.         }  
  112.     }  
  113.   
  114.     /** 
  115.      * logout operation 
  116.      *  
  117.      * @param request 
  118.      * @param response 
  119.      * @return 
  120.      */  
  121.     @RequestMapping(value = "/logout.html")  
  122.     public ModelAndView logout(HttpServletRequest request,  
  123.             HttpServletResponse response) {  
  124.   
  125.         /* 
  126.          * HttpServletRequest.getSession(ture) equals to 
  127.          * HttpServletRequest.getSession() means a new session created if no 
  128.          * session exists request.getSession(false) means if session exists get 
  129.          * the session,or value null 
  130.          */  
  131.         HttpSession session = request.getSession(false);  
  132.   
  133.         if (session != null) {  
  134.             session.invalidate();  
  135.         }  
  136.   
  137.         return new ModelAndView("redirect:/index.jsp");  
  138.     }  
  139.   
  140.     /** 
  141.      * check the Captcha code 
  142.      *  
  143.      * @param request 
  144.      * @param command 
  145.      * @return 
  146.      */  
  147.     protected Boolean validateCaptcha(HttpServletRequest request, Object command) {  
  148.         String captchaId = (String) request.getSession().getAttribute(  
  149.                 com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);  
  150.         String response = ((LoginCommand) command).getKaptchaCode();  
  151.         if (!StringUtils.equalsIgnoreCase(captchaId, response)) {  
  152.             return false;  
  153.         }  
  154.         return true;  
  155.     }  
  156. }  

         首先,看一下ajax的方式,在controller中我們認爲讓ajax拋出一樣,在頁面中我們採用js這樣調用

Js代碼  收藏代碼
  1. function ajaxTest()  
  2.     {  
  3.         $.ajax( {  
  4.             type : 'GET',  
  5.             //contentType : 'application/json',     
  6.             url : '${basePath}/josontest.html',     
  7.             async: false,//禁止ajax的異步操作,使之順序執行。  
  8.             dataType : 'json',  
  9.             success : function(data,textStatus){  
  10.                 alert(JSON.stringify(data));  
  11.             },  
  12.             error : function(data,textstatus){  
  13.                 alert(data.responseText);  
  14.             }  
  15.         });  
  16.     }  

         當拋出異常是,我們在js的error中採用 alert(data.responseText);將錯誤信息彈出,展現給用戶,具體頁面代碼如下:

Html代碼  收藏代碼
  1. <%@ page language="java" contentType="text/html; charset=UTF-8"  
  2.     pageEncoding="UTF-8"%>  
  3. <%@ include file="/common/taglibs.jsp"%>  
  4. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
  5. <html>  
  6.  <head>  
  7.   <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
  8.   <title>spring login information</title>  
  9.   <script type="text/javascript">  
  10.     function ajaxTest()  
  11.     {  
  12.         $.ajax( {  
  13.             type : 'GET',  
  14.             //contentType : 'application/json',     
  15.             url : '${basePath}/josontest.html',     
  16.             async: false,//禁止ajax的異步操作,使之順序執行。  
  17.             dataType : 'json',  
  18.             success : function(data,textStatus){  
  19.                 alert(JSON.stringify(data));  
  20.             },  
  21.             error : function(data,textstatus){  
  22.                 alert(data.responseText);  
  23.             }  
  24.         });  
  25.     }  
  26.   </script>  
  27.  </head>  
  28.  <body>  
  29.     <table cellpadding="0" cellspacing="0" style="width:100%;">  
  30.       <tr>  
  31.           <td rowspan="2" style="width:30px;">  
  32.           </td>  
  33.           <td style="height:72px;">  
  34.               <div>  
  35.                   spring login front information  
  36.               </div>  
  37.               <div>  
  38.                    ${loginedUser.userName},歡迎您進入Spring login information,您當前積分爲${loginedUser.credits};  
  39.               </div>  
  40.               <div>  
  41.                 <a href="${basePath}/backendmain.html">後臺管理</a>  
  42.              </div>  
  43.           </td>  
  44.            <td style="height:72px;">  
  45.               <div>  
  46.                 <input type=button value="Ajax Exception Test" onclick="ajaxTest();"></input>  
  47.              </div>  
  48.           </td>  
  49.           <td>  
  50.             <div>  
  51.             <a href="${basePath}/logout.html">退出</a>  
  52.            </div>  
  53.          </td>  
  54.       </tr>  
  55.     </table>  
  56.  </body>  
  57. </html>  

 驗證效果:

 



        至此,ajax方式起了作用,整個系統的異常統一處理方式做到了統一處理。我們在開發過程中無需關心,異常處理配置了。


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