SpringMVC对异常处理的支持

无论做什么项目,进行异常处理都是非常有必要的,而且你不能把一些只有程序员才能看懂的错误代码抛给用户去看,所以这时候进行统一的异常处理,展现一个比较友好的错误页面就显得很有必要了。跟其他MVC框架一样,springMVC也有自己的异常处理机制。

springMVC提供的异常处理主要有两种方式,一种是直接实现自己的HandlerExceptionResolver,当然这也包括使用Spring已经为我们提供好的SimpleMappingExceptionResolver和DefaultHandlerExceptionResolver,另一种是使用注解的方式实现一个专门用于处理异常的Controller——ExceptionHandler。

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

Java代码

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

上述的resolveException的第4个参数表示对哪种类型的异常进行处理。因为Exception类是所有异常类的基类,所以如果想根据异常类型的不同来进行不同的处理的话,可以在resolveException方法里面根据不同的异常类型进行不同的处理,返回不同的异常视图。如:

Java代码

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

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

Xml代码

  1. <bean id="exceptionResolver" class="com.tiantian.xxx.web.handler.ExceptionHandler"/>

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

以下是一个简单的例子:

(1)SpringMVC的servlet配置文件中申明一个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. @RequestMapping("/null")
  5. public void testNullPointerException() {
  6. Blog blog = null;
  7. //这里就会发生空指针异常,然后就会返回定义在SpringMVC配置文件中的null视图
  8. System.out.println(blog.getId());
  9. }
  10. @RequestMapping("/number")
  11. public void testNumberFormatException() {
  12. //这里就会发生NumberFormatException,然后就会返回定义在SpringMVC配置文件中的number视图
  13. Integer.parseInt("abc");
  14. }
  15. @RequestMapping("/default")
  16. public void testDefaultException() {
  17. if (1==1)
  18. //由于该异常类型在SpringMVC的配置文件中没有指定,所以就会返回默认的exception视图
  19. throw new RuntimeException("Error!");
  20. }
  21. }

(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. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  7. <html>
  8. <head>
  9. <base href="<%=basePath%>">
  10. <title>My JSP ‘number.jsp‘ starting page</title>
  11. <meta http-equiv="pragma" content="no-cache">
  12. <meta http-equiv="cache-control" content="no-cache">
  13. <meta http-equiv="expires" content="0">
  14. <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
  15. <meta http-equiv="description" content="This is my page">
  16. <!--
  17. <link rel="stylesheet" type="text/css" href="styles.css">
  18. -->
  19. </head>
  20. <body>
  21. NumberFormatException. <br>
  22. <%=exception.getMessage() %><br/>
  23. <%=exception %><br/><span style="color: #3366ff;"><!-- 这是JSP中的内置对象exception --></span>
  24. <%=request.getAttribute("ex") %><br><span style="color: #3366ff;"><!-- 这是SpringMVC放在返回的Model中的异常对象 --></span>
  25. <%=request.getAttribute("javax.servlet.error.status_code") %><span style="color: #3366ff;"><!-- HttpServletResponse返回的错误码信息,因为前面已经配置了NumberFormatException的错误码返回值为888,所以这里应该显示888 --></span>
  26. </body>
  27. </html>

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

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. import com.tiantian.blog.web.servlet.MyException;
  5. @Controller
  6. public class GlobalController {
  7. /**
  8. * 用于处理异常的
  9. * @return
  10. */
  11. @ExceptionHandler({MyException.class})
  12. public String exception(MyException e) {
  13. System.out.println(e.getMessage());
  14. e.printStackTrace();
  15. return "exception";
  16. }
  17. @RequestMapping("test")
  18. public void test() {
  19. throw new MyException("出错了!");
  20. }
  21. }

这里在页面上访问test方法的时候就会报错,而拥有该test方法的Controller又拥有一个处理该异常的方法,这个时候处理异常的方法就会被调用

优先级

既然在SpringMVC中有两种处理异常的方式,那么就存在一个优先级的问题:

当发生异常的时候,SpringMVC会如下处理:

(1)SpringMVC会先从配置文件找异常解析器HandlerExceptionResolver

(2)如果找到了异常异常解析器,那么接下来就会判断该异常解析器能否处理当前发生的异常

(3)如果可以处理的话,那么就进行处理,然后给前台返回对应的异常视图

(4)如果没有找到对应的异常解析器或者是找到的异常解析器不能处理当前的异常的时候,就看当前的Controller中有没有提供对应的异常处理器,如果提供了就由Controller自己进行处理并返回对应的视图

(5)如果配置文件里面没有定义对应的异常解析器,而当前Controller中也没有定义的话,那么该异常就会被抛出来。

时间: 2024-11-03 02:27:40

SpringMVC对异常处理的支持的相关文章

【Spring】18、springMVC对异常处理的支持

无论做什么项目,进行异常处理都是非常有必要的,而且你不能把一些只有程序员才能看懂的错误代码抛给用户去看,所以这时候进行统一的异常处理,展现一个比较友好的错误页面就显得很有必要了.跟其他MVC框架一样,springMVC也有自己的异常处理机制.springMVC提供的异常处理主要有两种方式,一种是直接实现自己的HandlerExceptionResolver,当然这也包括使用Spring已经为我们提供好的SimpleMappingExceptionResolver和DefaultHandlerEx

SpringMVC 全局异常处理

在 JavaEE 项目的开发中,不管是对底层的数据库操作过程,还是业务层的处理过程,还是控制层的处理过程,都不可避免会遇到各种可预知的.不可预知的异常需要处理.每个过程都单独处理异常,系统的代码耦合度高,工作量大且不好统一,维护的工作量也很大.SpringMvc 对于异常处理这块提供了支持,通过 SpringMvc 提供的全局异常处理机制,能够将所有类型的异常处从各处理过程解耦出来,这样既保证了相关处理过程的功能较单一,也实现了异常信息的统一处理和维护. 全局异常实现方式 Spring MVC

springMVC之异常处理

1. 自定义一个异常类: UserException.java public class UserException extends RuntimeException { private static final long serialVersionUID = 1L; public UserException() { super(); } public UserException(String message, Throwable cause) { super(message, cause);

springmvc的异常处理&amp;对静态的资源的处理

1 springmvc的异常处理方式,暂时我知道的两种 2 1.在controller中捕获 3 /** 4 * 捕获到异常,用于局部处理 5 * @ExceptionHandler (value={要捕获的异常,可以有多个}) 6 * @param e 7 * @param req 8 * @return 9 */ 10 @ExceptionHandler(value={UserException.class}) 11 public String handlerException(UserEx

springMVC多视图的支持

1.在springmvc.xml中加上 1 <!-- 多视图的支持 --> 2 <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver"> 3 <property name="contentNegotiationManager"> 4 <bean class="org.springframework.web.a

一起学SpringMVC之异常处理

在系统开发过程中,异常处理是不可避免,如果异常处理不好,会给用户造成很差的体验,本文主要讲解在SpringMVC开发过程中,异常处理的相关知识点,仅供学习分享使用,如有不足之处,还请指正. 概述 在SpringMvc中,处理异常有好几种方法,本文主要讲解两种方案: 通过@ExceptionHandler来进行异常的捕获接收并处理. 通过@ResponseStatus注解来进行返回状态码内容的自定义处理. 通过@ExceptionHandler操作步骤 1. 自定义一个异常类,继承自Excepti

【SpringMVC学习10】SpringMVC对RESTfull的支持

RESTful架构,就是目前流行的一种互联网软件架构.它结构清晰.符合标准.易于理解.扩展方便,所以正得到越来越多网站的采用.RESTful架构对url进行规范,写RESTful格式的url是什么样子的呢?我们一般请求的url是类似这样子的: http://...../xxx.action?id=001&type=aaa 而REST的url风格是什么样子呢?一般它类似于: http://..../xxx/001 所以REST有个很明显的特点:使url变得简洁,将参数通过url传到服务端.spri

【Spring】SpringMVC之异常处理

java中的异常分为两类,一种是运行时异常,一种是非运行时异常.在JavaSE中,运行时异常都是通过try{}catch{}捕获的,这种只能捕获显示的异常,通常项目上抛出的异常都是不可预见.那么我们能够有什么方法能够解决这种问题吗?当然有,SpringMVC中的异常处理机制就很好的做到了这一点. SpringMVC中的异常处理一共有3种方式 (1)使用Spring MVC提供的简单异常处理器SimpleMappingExceptionResolver: (2)实现Spring的异常处理接口Han

SpringMvc的异常处理

首先在SpringMVC中加上<mvc:annotation-driven>标签: <mvc:annotation-driven></mvc:annotation-driven> 新建一个error.jsp页面 1.基于注解的异常处理 (1)@ExceptionHandler注解 在当前Handler中定义由@ExceptionHandler注解修饰的方法,用于处理当前Handler中的异常信息! 在Handler中定义如下方法: 1 @ExceptionHandler