DispatcherServlet 默认装配的 HandlerExceptionResolver :
没有使用 <mvc:annotation-driven/> 配置:
使用了 <mvc:annotation-driven/> 配置:
实验代码 页面链接
<a href="testExceptionHandlerExceptionResolver?i=1">testExceptionHandlerExceptionResolver</a>
控制器方法package com.atguigu.springmvc.crud.handlers;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
public class ExceptionHandler {
@RequestMapping("/testExceptionHandlerExceptionResolver")
public String testExceptionHandlerExceptionResolver(@RequestParam("i") int i){
System.out.println("10/"+i+"="+(10/i));
return "success";
}
}
测试,出现异常情况处理异常,跳转到error.jsp
在控制器中增加处理异常的方法@ExceptionHandler(value={java.lang.ArithmeticException.class})
public String handleException(Exception ex){
System.out.println("出现异常啦L"+ex);
return "error";
}
增加error.jsp<h3>Error Page</h3>
// @ExceptionHandler(value={java.lang.ArithmeticException.class})
public String handleException(Exception ex,Map<String,Object> map){
System.out.println("出现异常啦:"+ex);
map.put("exception",ex);
return "error";
}
可以通过ModelAndView将异常对象传递给成功页面上@ExceptionHandler(value={java.lang.ArithmeticException.class})
public ModelAndView handleException(Exception ex){
System.out.println("出现异常啦:"+ex);
ModelAndView mv = new ModelAndView("error");
mv.addObject("exception", ex);
return mv;
}
@ExceptionHandler(value={java.lang.ArithmeticException.class})
public ModelAndView handleException(Exception ex){
System.out.println("出现异常啦:"+ex);
ModelAndView mv = new ModelAndView("error");
mv.addObject("exception", ex);
return mv;
}
@ExceptionHandler(value={java.lang.RuntimeException.class})
public ModelAndView handleException2(Exception ex){
System.out.println("RuntimeException-出现异常啦:"+ex);
ModelAndView mv = new ModelAndView("error");
mv.addObject("exception", ex);
return mv;
}
package com.atguigu.springmvc.exceptionAdvice;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;
@ControllerAdvice
public class ExceptionAdviceHandler {
/*
@ExceptionHandler(value={java.lang.ArithmeticException.class})
public ModelAndView handleException(Exception ex){
System.out.println("出现异常啦:"+ex);
ModelAndView mv = new ModelAndView("error");
mv.addObject("exception", ex);
return mv;
}*/
@ExceptionHandler(value={java.lang.RuntimeException.class})
public ModelAndView handleException2(Exception ex){
System.out.println("RuntimeException-出现异常啦:"+ex);
ModelAndView mv = new ModelAndView("error");
mv.addObject("exception", ex);
return mv;
}
}
org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver
Implementation of the HandlerExceptionResolver interface that uses the @ResponseStatus annotation to map exceptions to HTTP status codes.
This exception resolver is enabled by default in the
org.springframework.web.servlet.DispatcherServlet.
<a href="testResponseStatusExceptionResolver?i=10">testResponseStatusExceptionResolver</a>
自定义异常类package com.atguigu.springmvc.exception;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
/**
* 自定义异常类
HttpStatus.FORBIDDEN 不允许的,禁用的
*/
@ResponseStatus(value=HttpStatus.FORBIDDEN,reason="用户名称和密码不匹配")
public class UsernameNotMatchPasswordException extends RuntimeException{}
控制器方法@RequestMapping(value="/testResponseStatusExceptionResolver")
public String testResponseStatusExceptionResolver(@RequestParam("i") int i){
if(i==13){
throw new UsernameNotMatchPasswordException();
}
System.out.println("testResponseStatusExceptionResolver...");
return "success";
}
出现的错误消息没使用注解时:@ResponseStatus(value=HttpStatus.FORBIDDEN,reason="用户名称和密码不匹配") 使用注解时:@ResponseStatus(value=HttpStatus.FORBIDDEN,reason="用户名称和密码不匹配") 测试在方法上使用注解@ResponseStatus(value=HttpStatus.NOT_FOUND,reason="测试方法上设置响应状态码")
@RequestMapping(value="/testResponseStatusExceptionResolver")
public String testResponseStatusExceptionResolver(@RequestParam("i") int i){
if(i==13){
throw new UsernameNotMatchPasswordException();
}
System.out.println("testResponseStatusExceptionResolver...");
return "success";
}
ResponseStatus
package org.springframework.web.bind.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.http.HttpStatus;
/**
* Marks a method or exception class with the status code and reason that should be returned. The status code is applied
* to the HTTP response when the handler method is invoked, or whenever said exception is thrown.
*
* @author Arjen Poutsma
* @see org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver
* @since 3.0
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ResponseStatus {
HttpStatus value();
String reason() default "";
}
HttpStatusorg.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver
Default implementation of the HandlerExceptionResolver interface that resolves standard Spring exceptions and translates them to corresponding HTTP status codes.
This exception resolver is enabled by default in the org.springframework.web.servlet.DispatcherServlet.
<a href="testDefaultHandlerExceptionResolver">testDefaultHandlerExceptionResolver</a>
增加处理器方法
//@RequestMapping(value="/testDefaultHandlerExceptionResolver")
@RequestMapping(value="/testDefaultHandlerExceptionResolver",method=RequestMethod.POST) //不支持GET请求
public String testDefaultHandlerExceptionResolver(){
System.out.println("testDefaultHandlerExceptionResolver...");
return "success";
}
出现异常错误 出现异常交给DefaultHandlerExceptionResolver处理@Override
protected ModelAndView doResolveException(
HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
try {
if (ex instanceof NoSuchRequestHandlingMethodException) {
return handleNoSuchRequestHandlingMethod((NoSuchRequestHandlingMethodException) ex, request, response,
handler);
}
else if (ex instanceof HttpRequestMethodNotSupportedException) {
return handleHttpRequestMethodNotSupported((HttpRequestMethodNotSupportedException) ex, request,
response, handler);
}
else if (ex instanceof HttpMediaTypeNotSupportedException) {
return handleHttpMediaTypeNotSupported((HttpMediaTypeNotSupportedException) ex, request, response,
handler);
}
else if (ex instanceof HttpMediaTypeNotAcceptableException) {
return handleHttpMediaTypeNotAcceptable((HttpMediaTypeNotAcceptableException) ex, request, response,
handler);
}
else if (ex instanceof MissingServletRequestParameterException) {
return handleMissingServletRequestParameter((MissingServletRequestParameterException) ex, request,
response, handler);
}
else if (ex instanceof ServletRequestBindingException) {
return handleServletRequestBindingException((ServletRequestBindingException) ex, request, response,
handler);
}
else if (ex instanceof ConversionNotSupportedException) {
return handleConversionNotSupported((ConversionNotSupportedException) ex, request, response, handler);
}
else if (ex instanceof TypeMismatchException) {
return handleTypeMismatch((TypeMismatchException) ex, request, response, handler);
}
else if (ex instanceof HttpMessageNotReadableException) {
return handleHttpMessageNotReadable((HttpMessageNotReadableException) ex, request, response, handler);
}
else if (ex instanceof HttpMessageNotWritableException) {
return handleHttpMessageNotWritable((HttpMessageNotWritableException) ex, request, response, handler);
}
else if (ex instanceof MethodArgumentNotValidException) {
return handleMethodArgumentNotValidException((MethodArgumentNotValidException) ex, request, response, handler);
}
else if (ex instanceof MissingServletRequestPartException) {
return handleMissingServletRequestPartException((MissingServletRequestPartException) ex, request, response, handler);
}
else if (ex instanceof BindException) {
return handleBindException((BindException) ex, request, response, handler);
}
else if (ex instanceof NoHandlerFoundException) {
return handleNoHandlerFoundException((NoHandlerFoundException) ex, request, response, handler);
}
}
catch (Exception handlerException) {
logger.warn("Handling of [" + ex.getClass().getName() + "] resulted in Exception", handlerException);
}
return null;
}
<a href="testSimpleMappingExceptionResolver?i=1">testSimpleMappingExceptionResolver</a>
增加控制器方法@RequestMapping("/testSimpleMappingExceptionResolver")
public String testSimpleMappingExceptionResolver(@RequestParam("i") int i){
System.out.println("testSimpleMappingExceptionResolver...");
String[] s = new String[10];
System.out.println(s[i]);
return "success";
}
出现异常情况:参数i的值大于10 配置异常解析器:自动将异常对象信息,存放到request范围内<!-- 配置SimpleMappingExceptionResolver异常解析器 -->
<bean id="simpleMappingExceptionResolver"
class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<!-- exceptionAttribute默认值(通过ModelAndView传递给页面):
exception -> ${requestScope.exception}
public static final String DEFAULT_EXCEPTION_ATTRIBUTE = "exception";
-->
<property name="exceptionAttribute" value="exception"></property>
<property name="exceptionMappings">
<props>
<prop key="java.lang.ArrayIndexOutOfBoundsException">error</prop>
</props>
</property>
</bean>
error.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h3>Error Page</h3>
${exception }
${requestScope.exception }
</body>
</html>
源码分析SimpleMappingExceptionResolver L187 L339
@Override
protected ModelAndView doResolveException(HttpServletRequest request,
HttpServletResponse response,Object handler, Exception ex) {
// Expose ModelAndView for chosen error view.
String viewName = determineViewName(ex, request);
if (viewName != null) {
// Apply HTTP status code for error views, if specified.
// Only apply it if we're processing a top-level request.
Integer statusCode = determineStatusCode(request, viewName);
if (statusCode != null) {
applyStatusCodeIfPossible(request, response, statusCode);
}
return getModelAndView(viewName, ex, request);
}else {
return null;
}
}
/**
* Return a ModelAndView for the given view name and exception.
* <p>The default implementation adds the specified exception attribute.
* Can be overridden in subclasses.
* @param viewName the name of the error view
* @param ex the exception that got thrown during handler execution
* @return the ModelAndView instance
* @see #setExceptionAttribute
*/
protected ModelAndView getModelAndView(String viewName, Exception ex) {
ModelAndView mv = new ModelAndView(viewName);
if (this.exceptionAttribute != null) {
if (logger.isDebugEnabled()) {
logger.debug("Exposing Exception as model attribute '" + this.exceptionAttribute + "'");
}
mv.addObject(this.exceptionAttribute, ex);
}
return mv;
}