springmvc--异常处理

首先来回忆一下,

struts2是如何得来处理异常的,在Action里面无需处理异常, 在配置文件中通过exception节点来配置,当Action里面抛出异常的时候,

根据配置文件中的配置来跳转到响应的页面,在页面上可以通过OGNL来打印异常信息。

 

那么springmvc是如何来处理异常的?

springmvc通过HandlerExceptionResolver处理程序的异常,包括Handler映射,数据绑定以及目标方法执行发生的异常。

springmvc提供的HandlerExceptionResolver的实现类

springmvc--异常处理_第1张图片

 其中,

ExceptionHandlerExceptionResolver是用来处理@ExceptionHandler注解的方法

示例如下

    /**
     * 1.在@ExceptionHandler标记的方法的入参中可以加入Exception类型的参数,该参数即对应发生的异常对象
     * 2.@ExceptionHandler方法的入参中不能传入Map,若希望把异常信息传入错误画面上,需要使用ModelAndView
     * 3.@ExceptionHandler方法标记的异常有优先级的问题,
     * 即如果此时还有一个标记了@ExceptionHandler的方法,捕获异常是RunTimeException的话,则更匹配的异常优先
     * 4.如果在对应的Controller中找不到@ExceptionHandler标记的方法,则会去标记了@ControllerAdvice标记的类中查找@ExceptionHandler方法
     * @param ex
     * @return
     */
    @ExceptionHandler({ArithmeticException.class}) public ModelAndView exceptionHandler(Exception ex){ System.out.println("出异常了!!!!"); ModelAndView mv = new ModelAndView("error"); mv.addObject("exception", ex); return mv; } @RequestMapping("testExceptionHandler") public String testExceptionHandler(@RequestParam("i") Integer i){ int result = 10/i; System.out.println("testExceptionHandler result: " + result); return "success"; }

 

上面的@ExceptionHandler标记的方法只能处理当前的handler中的异常,如果需要处理所有的handler的某一类型异常应该怎么做呢?

答案就是定义一个标记了@ControllerAdvice的类来统一处理,代码如下:

@ControllerAdvice
public class MyExceptionHandler { @ExceptionHandler({ArithmeticException.class}) public ModelAndView exceptionHandler(Exception ex){ System.out.println("@ControllerAdvice[出异常了!!!]"); ModelAndView mv = new ModelAndView("error"); mv.addObject("exception", ex); return mv; } }

 

ResponseStatusExceptionResolver是用来处理@ResponseStatus注解的,错误页面自定义状态码和消息,

效果如下

springmvc--异常处理_第2张图片

是如何实现的呢,很简单,只要在自定义的异常的上面追加@ResponseStatus

@ResponseStatus(value=HttpStatus.BAD_REQUEST,reason="这是一个异常消息")
public class MyException extends RuntimeException {

    private static final long serialVersionUID = 2880943887356567043L;
}

 

 

DefaultHandlerExceptionResolver是用来处理springmvc特殊的异常进行处理,比如由于方式不同,导致找不到对应的方法,效果如下:

springmvc--异常处理_第3张图片

 

SimpleMappingExceptionResolver是,如果希望对所有异常进行统一处理,他将异常类名映射为试图名,

在springmvc的容器中,如下配置

<bean
        class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
        <property name="defaultErrorView" value="error"></property>
        <property name="exceptionAttribute" value="ex"></property>
        <property name="exceptionMappings">
            <props>
                <prop key="MyException1的全类名">error1</prop>
                <prop key="MyException2的全类名">error2</prop>
            </props>
        </property>
    </bean>

 

 

自定义异常处理器 

@Controller注解的类中,添加如下测试代码(如果参数kind是1,则抛出MyException1,如果参数kind是2,则抛出MyException2)

@RequestMapping("testException")
public String testException(@RequestParam("kind") Integer kind) throws MyException1, MyException2{

if(kind == 1){
throw new MyException1("this is Exception One!!");
}else if(kind == 2){
throw new MyException2("this is Exception two");
}

return "success";
}

自定义异常MyException1和MyException2

自定义MyExceptionHandler,代码如下

public class MyExceptionHandler implements HandlerExceptionResolver {

    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { Map<String, Object> model = new HashMap<String, Object>(); model.put("ex", ex); if(ex instanceof MyException1){ return new ModelAndView("error1", model);
           // 对应页面 error1.jsp }else if(ex instanceof MyException2){ return new ModelAndView("error2", model);
          // 对应页面 error2.jsp } return new ModelAndView("error", model);
// 对应页面error } }

 

另外DispatcherSerlvet默认装配的HandlerExceptionResolver

(注意点:由于AnnotationMethodHandlerExceptionResolver已经过期了,所以开发中都需要配置<mvc:annotation-driven ></mvc:annotation-driven>)

springmvc--异常处理_第4张图片

 

你可能感兴趣的:(springmvc--异常处理)