spring mvc 异常统一处理

简介: 三. spring mvc 异常统一处理 博客分类:  spring3系列  SpringMVC 提供的异常处理主要有两种方式,一种是直接实现自己的HandlerExceptionResolver,另一种是使用注解的方式实现一个专门用于处理异常的Controller——ExceptionHandler。

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. 针对Spring MVC 框架,修改代码实现普通异常及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.分析spring源码,自定义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方式起了作用,整个系统的异常统一处理方式做到了统一处理。我们在开发过程中无需关心,异常处理配置了。

相关文章
|
1月前
|
缓存 前端开发 Java
Spring MVC 面试题及答案整理,最新面试题
Spring MVC 面试题及答案整理,最新面试题
88 0
|
1月前
|
SQL JavaScript Java
springboot+springm vc+mybatis实现增删改查案例!
springboot+springm vc+mybatis实现增删改查案例!
25 0
|
1月前
|
SQL Java 数据库连接
挺详细的spring+springmvc+mybatis配置整合|含源代码
挺详细的spring+springmvc+mybatis配置整合|含源代码
40 1
|
10天前
|
数据采集 前端开发 Java
数据塑造:Spring MVC中@ModelAttribute的高级数据预处理技巧
数据塑造:Spring MVC中@ModelAttribute的高级数据预处理技巧
22 3
|
10天前
|
存储 前端开发 Java
会话锦囊:揭示Spring MVC如何巧妙使用@SessionAttributes
会话锦囊:揭示Spring MVC如何巧妙使用@SessionAttributes
13 1
|
10天前
|
前端开发 Java Spring
数据之桥:深入Spring MVC中传递数据给视图的实用指南
数据之桥:深入Spring MVC中传递数据给视图的实用指南
29 3
|
20天前
|
前端开发 安全 Java
使用Java Web框架:Spring MVC的全面指南
【4月更文挑战第3天】Spring MVC是Spring框架的一部分,用于构建高效、模块化的Web应用。它基于MVC模式,支持多种视图技术。核心概念包括DispatcherServlet(前端控制器)、HandlerMapping(请求映射)、Controller(处理请求)、ViewResolver(视图解析)和ModelAndView(模型和视图容器)。开发流程涉及配置DispatcherServlet、定义Controller、创建View、处理数据、绑定模型和异常处理。
使用Java Web框架:Spring MVC的全面指南
|
26天前
|
敏捷开发 监控 前端开发
Spring+SpringMVC+Mybatis的分布式敏捷开发系统架构
Spring+SpringMVC+Mybatis的分布式敏捷开发系统架构
59 0
|
3月前
|
开发框架 前端开发 .NET
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
41 0
|
8月前
|
存储 开发框架 前端开发
[回馈]ASP.NET Core MVC开发实战之商城系统(五)
经过一段时间的准备,新的一期【ASP.NET Core MVC开发实战之商城系统】已经开始,在之前的文章中,讲解了商城系统的整体功能设计,页面布局设计,环境搭建,系统配置,及首页【商品类型,banner条,友情链接,降价促销,新品爆款】,商品列表页面,商品详情等功能的开发,今天继续讲解购物车功能开发,仅供学习分享使用,如有不足之处,还请指正。
114 0