通过HandlerExceptionResolver接口来处理异常。
AnnotationMethodHandlerExceptionResolver
ResponseStatusExceptionResolver
DefaultHandlerExceptionResolver
-配置了<mvc:annotation-driver/>
ExceptionHandlerExceptionResolver
ResponseStatusExceptionResolver
DefaultHandlerExceptionResolver
1)处理Handler类内部的异常
ControllerAdvice处理异常的优先级会低于1)中Handler内部的异常处理。
当修饰URL函数时,只要访问该路径,跳到相应的错误码页面,不管是否真正的出错误。
如下配置,当发生自定义异常MyUnAuthorizedException时,就会跳转到对应的视图error中。
1.DispatcherServlet默认装配的HandlerExceptionResolver
-没有配置<mvc:annotation-driver/>:AnnotationMethodHandlerExceptionResolver
ResponseStatusExceptionResolver
DefaultHandlerExceptionResolver
-配置了<mvc:annotation-driver/>
ExceptionHandlerExceptionResolver
ResponseStatusExceptionResolver
DefaultHandlerExceptionResolver
2.ExceptionHandlerExceptionResolver
该配置内容主要用来处理 @ExceptionHandler 注解的方法。1)处理Handler类内部的异常
如下实例代码所示,当testException传入的是0时,会出现0除异常,这时由于添加了ExceptionHanlder注解,SpringMVC会自动将该异常交给hanlder内部定义的handleException函数来处理。
注意:如果不将异常传到view中,则只需要返回view名即可。若想将对象传到view中,则必须使用ModelAndView,不可以使用参数中Map的形式。但是这里每次测试时会跳转到 /spring/WEB-INF/views/testException.jsp ,而不是指定的error.jsp.不知道什么原因。
package spring;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.portlet.ModelAndView;
@Controller
public class TestExceptionController {
@ExceptionHandler({NullPointerException.class, ArithmeticException.class})
public ModelAndView handleException(ArithmeticException ex){
System.out.println("异常:" + ex);
ModelAndView mv = new ModelAndView("error");
mv.addObject("exception", ex);
return mv;
}
@RequestMapping("/testException")
public String testException(@RequestParam("data") int data){
System.out.println("Result:" + 10/data);
return "success";
}
}
2)处理整个WebApp的异常
ControllerAdvice处理异常的优先级会低于1)中Handler内部的异常处理。
package spring;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
@ControllerAdvice //加上该注解后,该handler就可以处理全局的Exception啦。
public class GlobalExceptionHandler {
@ExceptionHandler({ArithmeticException.class})
public String testGlobalExceptionHanlder(Exception ex)
{
System.out.println("testGlobalExceptionHanlder:" + ex);
return "error";
}
}
3.ResponseStatusExceptionResolver处理异常
该类用来处理被@ResponseStatus注解的内容。1)修饰类
如下自定义异常类,当该异常被触发时,会返回@ResponseStatus定义的Http码以及错误原因。
@ResponseStatus(value=HttpStatus.UNAUTHORIZED, reason="没有权限访问")
public class MyUnAuthorizedException extends RuntimeException {
private static final long serialVersionUID = 1L;
}
对应的Controller代码如下
@Controller
public class TestController {
@RequestMapping("testResponseStatusExceptionResolver")
public String testResponseStatusExceptionResolver(@RequestParam("isAuthorized") boolean isAuthorized){
if(isAuthorized){
return "success";
}else
{
throw new MyUnAuthorizedException();
}
}
}
2)修饰函数
当修饰URL函数时,只要访问该路径,跳到相应的错误码页面,不管是否真正的出错误。
@Controller
public class TestController {
@ResponseStatus(value=HttpStatus.UNAUTHORIZED, reason="不管怎么访问都提示错误")
@RequestMapping("testResponseStatusExceptionResolver")
public String testResponseStatusExceptionResolver(@RequestParam("isAuthorized") boolean isAuthorized){
if(isAuthorized){
return "success";
}else
{
throw new MyUnAuthorizedException();
}
}
}
4.DefaultHandlerExceptionResolver
将SpringMVC的标准异常转换成Http错误状态码。是用来处理SpringMVC内部异常的,通常我们不会直接使用。5.SimpleMappingExceptionResolver
可以在<servlet-name>-servlet.xml中通过一个简单的异常和URL映射,来配置异常如何处理。如下配置,当发生自定义异常MyUnAuthorizedException时,就会跳转到对应的视图error中。
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<prop key="myspring.MyUnAuthorizedException">error</prop>
</props>
</property>
</bean>
<完>