SpringMVC异常处理

来源:互联网 发布:mac粉色系口红推荐 编辑:程序博客网 时间:2024/04/29 20:15

SpringMVC通过 HandlerExceptionResolver 处理程序异常,包括处理器映射、数据绑定以及处理器执行时发生的异常。

public interface HandlerExceptionResolver {   ModelAndView resolveException(         HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex);} 

当异常发生时,SpringMVC将调用 resolveException 方法,并转到ModelAndView对应的视图中,作为一个异常报告页面反馈给用户。

它的实现类:



SpringMVC默认装配的异常处理器:


在spring-webmvc-4.3.10.RELEASE.jar!\org\springframework\web\servlet\DispatcherServlet.properties

也可以查看到:


当我们在SpringMVC文件中标注了:

<mvc:annotation-driven/>

则默认装配的异常处理器为:


一般在项目中,我们都会使用:<mvc:annotation-driven/>。

另外AnnotationMethodHandlerExceptionResolver被标注为:@deprecated as of Spring 3.2, in favor of ExceptionHandlerExceptionResolver,

即不再被建议使用。

ExceptionHandlerExceptionResolver

主要处理 Handler 中用 @ExceptionHandler 注解定义的方法。
-- @ExceptionHandler 注解定义的方法可以加入Exception类型的参数,该参数即对应发生的异常对象。
--@ExceptionHandler 注解定义的方法优先级问题:例如发生的是NullPointerException,但是声明的异常有 RuntimeException 和 Exception,此时会根据异常的最近
继承关系找到继承深度最浅的那个@ExceptionHandler 注解方法,即标记了 RuntimeException 的方法
--ExceptionHandlerMethodResolver 内部若找不到@ExceptionHandler 注解的话,会找 @ControllerAdvice 中的@ExceptionHandler 注解方法
测试:
@ExceptionHandler({ArithmeticException.class, ArrayIndexOutOfBoundsException.class})    public ModelAndView handlerArithmeticException(Exception ex) {        ModelAndView mv = new ModelAndView("error");        mv.addObject("exception", ex);        System.out.println("发生异常:" + ex);        return mv;    }    @RequestMapping("/testException")    public String testException(@RequestParam("i") int i) {        //System.out.println("result = " + 10 / i);        int arr[] = {1, 2, 3, 4};        System.out.println(arr[5]);        return "hello";    }
这样就可以在error页面显示异常信息。handlerArithmeticException方法中可以传入Model参数,但是传入Map,ModelMap则报错。
java.lang.IllegalStateException: Could not resolve method parameter at index 1 in public java.lang.String com.xiya.controller.TestController.handlerArithmeticException(java.lang.Exception,org.springframework.ui.ModelMap): No suitable resolver for argument 1 of type 'org.springframework.ui.ModelMap'
ExceptionHandler注解中可以传入Throwable类型的参数,该参数即对应发生的异常对象。
该异常处理器的处理范围仅仅针对以上Controller,要想获得全局的效果需要自己配置异常处理类。
package com.xiya.controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.ControllerAdvice;import org.springframework.web.bind.annotation.ExceptionHandler;/** * Created by N3verL4nd on 2017/5/25. */@ControllerAdvicepublic class ExceptionHandlers {     @ExceptionHandler({ArithmeticException.class, ArrayIndexOutOfBoundsException.class})    public String handlerArithmeticException(Exception ex, Model model) {        model.addAttribute("exception", ex);        System.out.println("发生异常2:" + ex);        return "error";    }}

ResponseStatusExceptionResolver

使用 @ResponseStatus 注解把异常转化为HTTP响应的状态码。
package com.xiya.controller.test;import org.springframework.http.HttpStatus;import org.springframework.web.bind.annotation.ResponseStatus;/** * Created by N3verL4nd on 2017/5/25. */@ResponseStatus(code = HttpStatus.NOT_FOUND, reason = "没有该用户")public class UserNotFoundException extends RuntimeException {}
@RequestMapping(value = "/test2")    public String test2(@RequestParam("i") int i) {        if (i == 100) {            throw new UserNotFoundException();        }        return "hello";    }



DefaultHandlerExceptionResolver

将SpringMVC框架的异常转化为相应的响应状态码。
对于:
else if (ex instanceof HttpRequestMethodNotSupportedException) {   return handleHttpRequestMethodNotSupported((HttpRequestMethodNotSupportedException) ex, request,         response, handler);}
当我们以get方式请求如下方法时:DefaultHandlerExceptionResolver-->doResolveException
@RequestMapping(value = "/test2", method = RequestMethod.POST)    public String test2() {        return "hello";    }
将会导致该异常发生。


SimpleMappingExceptionResolver

继承自AbstractHandlerExceptionResolver抽象类,是1个根据配置进行解析异常的类,包括配置异常类型,默认的错误视图,默认的响应码,异常映射等配置属性。
如果希望对所有的异常进行统一的处理,可以使用SimpleMappingExceptionResolver,它将异常类型映射为视图名。
即可以通过配置XML,发生某一异常,然后转向该异常的视图解析器页面。
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">        <property name="exceptionMappings">            <props>                <prop key="ArrayIndexOutOfBoundsException">error</prop>            </props>        </property>        <property name="exceptionAttribute" value="exception"/>    </bean>

@RequestMapping(value = "/test4", method = RequestMethod.GET)    @ResponseBody    public String test4(@RequestParam("i") int i) {        System.out.println("result = " + 10 / i);        int[] arr = new int[10];        System.out.println(arr[i]);        return "test4";    }

在异常页面error.jsp就可以通过
${requestScope.exception}
引用该异常了。

测试:
curl http://localhost:8080/WebDemo/test4?i=10
<html>
<head>
    <title>异常页面</title>
</head>
<body>
    <h1>异常</h1>
    java.lang.ArrayIndexOutOfBoundsException: 10
</body>
</html>


参考:
http://www.cnblogs.com/fangjian0423/p/springMVC-exception-analysis.html

原创粉丝点击