程序员人生 网站导航

SpringMVC对异常处理的支持

栏目:综合技术时间:2015-01-07 08:11:04

不管做甚么项目,进行异常处理都是非常有必要的,而且你不能把1些只有程序员才能看懂的毛病代码抛给用户去看,所以这时候候进行统1的异常处理,展现1个比较友好的毛病页面就显得很有必要了。跟其他MVC框架1样,springMVC也有自己的异常处理机制。
springMVC提供的异常处理主要有两种方式,1种是直接实现自己的HandlerExceptionResolver,固然这也包括使用Spring已为我们提供好的SimpleMappingExceptionResolver和DefaultHandlerExceptionResolver,另外一种是使用注解的方式实现1个专门用于处理异常的Controller――ExceptionHandler。


1、实现自己的HandlerExceptionResolver,HandlerExceptionResolver是1个接口,springMVC本身已对其有了1个本身的实现――DefaultHandlerExceptionResolver,该解析器只是对其中的1些比较典型的异常进行了拦截,然后返回对应的毛病码,固然你也能够继承DefaultHandlerExceptionResolver类,然后重写其中的1些异常处理方法来实现自己的异常处理。

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个参数表示对哪一种类型的异常进行处理。由于Exception类是所有异常类的基类,所以如果想根据异常类型的不同来进行不同的处理的话,可以在resolveException方法里面根据不同的异常类型进行不同的处理,返回不同的异常视图。如:

Java代码
 收藏代码
  1. public class ExceptionHandler implements HandlerExceptionResolver {  
  2.   
  3.     @Override  
  4.     public ModelAndView resolveException(HttpServletRequest request,  
  5.             HttpServletResponse response, Object handler, Exception ex) {  
  6.         // TODO Auto-generated method stub  
  7.         if (ex instanceof NumberFormatException) {  
  8.             //doSomething...  
  9.             return new ModelAndView("number");  
  10.         } else if (ex instanceof NullPointerException) {  
  11.             //doSomething...  
  12.             return new ModelAndView("null");  
  13.         }  
  14.         return new ModelAndView("exception");  
  15.     }  
  16.   
  17. }  
 

 

定义了这样1个异常处理器以后就要在applicationContext中定义这样1个bean对象,如:

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

Spring除实现了1个DefaultHandlerExceptionResolver以外,还实现了1个SimpleMappingExceptionResolver,这二者都是继承自抽象类AbstractHandlerExceptionResolver,而AbstractHandlerExceptionResolver是实现了HandlerExceptionResolver接口的resolveException方法的,并由此抽取出两个抽象方法,1个是在进行异常处理之前履行的方法prepareResponse(exception, response),1个是进行异常解析的doResolveException(request, response, handler, exception)方法。SimpleMappingExceptionResolver,顾名思义就是通过简单的映照关系来决定由哪一个视图来处应当前的毛病信息。SimpleMappingExceptionResolver提供了通过异常类型exceptionMappings来进行异常与视图之间的映照关系,提供了在产生异常时通过statusCodes来映照异常返回的视图名称和对应的HttpServletResponse的返回码。而且可以通过defaultErrorView和defaultErrorCode来指定默许值,defaultErrorView表示当没有在exceptionMappings里面找到对应的异常类型时就返回defaultErrorView定义的视图,defaultErrorCode表示在产生异常时当没有在视图与返回码的映照关系statusCodes里面找到对应的映照时默许返回的返回码。在使用SimpleMappingExceptionResolver时,当产生异常的时候,SimpleMappingExceptionResolver将会把当前的异常对象放到本身属性exceptionAttribute中,当没有指定exceptionAttribute时,exceptionAttribute就是用默许值exception。

以下是1个简单的例子:

(1)SpringMVC的servlet配置文件中申明1个SimpleMappingExceptionResolver bean,并通过配置属性exceptionMappings和defaultExceptionView来指定异常和视图的对应关系。

Xml代码
 收藏代码
  1. <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">  
  2.     <property name="exceptionMappings">  
  3.         <props>  
  4.             <prop key="NumberFormatException">number</prop><!-- 表示当抛出NumberFormatException的时候就返回名叫number的视图 -->  
  5.             <prop key="NullPointerException">null</prop>  
  6.         </props>  
  7.     </property>  
  8.     <property name="defaultErrorView" value="exception"/><!-- 表示当抛出异常但没有在exceptionMappings里面找到对应的异常时 返回名叫exception的视图-->  
  9.     <property name="statusCodes"><!-- 定义在产生异常时视图跟返回码的对应关系 -->  
  10.         <props>  
  11.             <prop key="number">500</prop><!-- 表示在产生NumberFormatException时返回视图number,然后这里定义产生异常时视图number对应的HttpServletResponse的返回码是500 -->  
  12.             <prop key="null">503</prop>  
  13.         </props>  
  14.     </property>  
  15.     <property name="defaultStatusCode" value="404"/><!-- 表示在产生异常时默许的HttpServletResponse的返回码是多少,默许是200 -->  
  16. </bean>  

(2)以下访问:

Java代码
 收藏代码
  1. @Controller  
  2. @RequestMapping("/test")  
  3. public class TestController {  
  4.   
  5.     @RequestMapping("/null")  
  6.     public void testNullPointerException() {  
  7.         Blog blog = null;  
  8.         //这里就会产生空指针异常,然后就会返回定义在SpringMVC配置文件中的null视图  
  9.         System.out.println(blog.getId());  
  10.     }  
  11.       
  12.     @RequestMapping("/number")  
  13.     public void testNumberFormatException() {  
  14.         //这里就会产生NumberFormatException,然后就会返回定义在SpringMVC配置文件中的number视图  
  15.         Integer.parseInt("abc");  
  16.     }  
  17.       
  18.     @RequestMapping("/default")  
  19.     public void testDefaultException() {  
  20.         if (1==1)  
  21.             //由于该异常类型在SpringMVC的配置文件中没有指定,所以就会返回默许的exception视图  
  22.             throw new RuntimeException("Error!");  
  23.     }  
  24.       
  25. }  

 

(3)Jsp页面中可以访问到的异常对象,这里以NumberFormatException的返回视图number.jsp作为示例:

Jsp代码
 收藏代码
  1. <%@ page language="java" import="java.util.*" pageEncoding="GB18030" isErrorPage="true"%>  
  2. <%  
  3. String path = request.getContextPath();  
  4. String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  
  5. %>  
  6.   
  7. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
  8. <html>  
  9.   <head>  
  10.     <base href="<%=basePath%>">  
  11.       
  12.     <title>My JSP 'number.jsp' starting page</title>  
  13.       
  14.     <meta http-equiv="pragma" content="no-cache">  
  15.     <meta http-equiv="cache-control" content="no-cache">  
  16.     <meta http-equiv="expires" content="0">      
  17.     <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">  
  18.     <meta http-equiv="description" content="This is my page">  
  19.     <!--  
  20.     <link rel="stylesheet" type="text/css" href="styles.css">  
  21.     -->  
  22.   
  23.   </head>  
  24.     
  25.   <body>  
  26.     NumberFormatException. <br>  
  27.     <%=exception.getMessage() %><br/>  
  28.     <%=exception %><br/><span style="color: #3366ff;"><!-- 这是JSP中的内置对象exception --></span>  
  29.   
  30.   
  31.   
  32.     <%=request.getAttribute("ex") %><br><span style="color: #3366ff;"><!-- 这是SpringMVC放在返回的Model中的异常对象 --></span>  
  33.   
  34.   
  35.   
  36.     <%=request.getAttribute("javax.servlet.error.status_code") %><span style="color: #3366ff;"><!-- HttpServletResponse返回的毛病码信息,由于前面已配置了NumberFormatException的毛病码返回值为888,所以这里应当显示888 --></span>  
  37.   
  38.   
  39.   
  40.   </body>  
  41. </html>  
   

(4)当要求/test/number.do的时候会返回定义好的number视图,返回结果以下:


 

2、使用@ExceptionHandler进行处理

使用@ExceptionHandler进行处理有1个不好的地方是进行异常处理的方法必须与出错的

------分隔线----------------------------
------分隔线----------------------------

最新技术推荐