社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
afterCompletion():这个方法在 DispatcherServlet 完全处理完请求后被调用,可以在该方法中进行一些资源清理的操作。
package com.atguigu.springmvc.interceptors;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView;
public class FirstHandlerInterceptor implements HandlerInterceptor {
@Override public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception { System.out.println(this.getClass().getName() + " - afterCompletion"); }
@Override public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception { System.out.println(this.getClass().getName() + " - postHandle"); }
@Override public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception { System.out.println(this.getClass().getName() + " - preHandle"); return true; } } |
<mvc:interceptors> <!-- 声明自定义拦截器 --> <bean id="firstHandlerInterceptor" class="com.atguigu.springmvc.interceptors.FirstHandlerInterceptor"></bean> </mvc:interceptors> |
package com.atguigu.springmvc.interceptors;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView;
public class FirstHandlerInterceptor implements HandlerInterceptor {
@Override public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception { System.out.println(this.getClass().getName() + " - afterCompletion"); }
@Override public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception { System.out.println(this.getClass().getName() + " - postHandle"); }
@Override public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception { System.out.println(this.getClass().getName() + " - preHandle"); return true; }
} |
package com.atguigu.springmvc.interceptors;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView;
public class SecondHandlerInterceptor implements HandlerInterceptor {
@Override public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception { System.out.println(this.getClass().getName() + " - afterCompletion"); }
@Override public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception { System.out.println(this.getClass().getName() + " - postHandle"); }
@Override public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception { System.out.println(this.getClass().getName() + " - preHandle"); return true; }
} |
<mvc:interceptors> <!-- 声明自定义拦截器 --> <bean id="firstHandlerInterceptor" class="com.atguigu.springmvc.interceptors.FirstHandlerInterceptor"></bean> <!-- 配置拦截器引用 --> <mvc:interceptor> <mvc:mapping path="/empList"/> <!-- <mvc:exclude-mapping path="/empList"/> --> <bean id="secondHandlerInterceptor" class="com.atguigu.springmvc.interceptors.SecondHandlerInterceptor"></bean> </mvc:interceptor> </mvc:interceptors> |
两个都是返回true : com.atguigu.springmvc.interceptors.FirstHandlerInterceptor - preHandle com.atguigu.springmvc.interceptors.SecondHandlerInterceptor - preHandle ************************************biz method******************************* com.atguigu.springmvc.interceptors.SecondHandlerInterceptor - postHandle com.atguigu.springmvc.interceptors.FirstHandlerInterceptor - postHandle com.atguigu.springmvc.interceptors.SecondHandlerInterceptor - afterCompletion com.atguigu.springmvc.interceptors.FirstHandlerInterceptor - afterCompletion |
两个都是返回false: com.atguigu.springmvc.interceptors.FirstHandlerInterceptor - preHandle |
true,false com.atguigu.springmvc.interceptors.FirstHandlerInterceptor - preHandle com.atguigu.springmvc.interceptors.SecondHandlerInterceptor - preHandle com.atguigu.springmvc.interceptors.FirstHandlerInterceptor - afterCompletion |
false,true |
com.atguigu.springmvc.interceptors.FirstHandlerInterceptor - preHandle |
com.atguigu.springmvc.interceptors.FirstHandlerInterceptor - preHandle com.atguigu.springmvc.interceptors.SecondHandlerInterceptor – preHandle ************************************biz method******************************* com.atguigu.springmvc.interceptors.SecondHandlerInterceptor - postHandle com.atguigu.springmvc.interceptors.FirstHandlerInterceptor - postHandle com.atguigu.springmvc.interceptors.SecondHandlerInterceptor - afterCompletion com.atguigu.springmvc.interceptors.FirstHandlerInterceptor - afterCompletion |
boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception { if (getInterceptors() != null) { for (int i = 0; i < getInterceptors().length; i++) { HandlerInterceptor interceptor = getInterceptors()[i]; if (!interceptor.preHandle(request, response, this.handler)) { triggerAfterCompletion(request, response, null); return false; } this.interceptorIndex = i; } } return true; } |
void applyPostHandle(HttpServletRequest request, HttpServletResponse response, ModelAndView mv) throws Exception { if (getInterceptors() == null) { return; } for (int i = getInterceptors().length - 1; i >= 0; i--) { HandlerInterceptor interceptor = getInterceptors()[i]; interceptor.postHandle(request, response, this.handler, mv); } }
|
void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, Exception ex) throws Exception {
if (getInterceptors() == null) { return; } for (int i = this.interceptorIndex; i >= 0; i--) { HandlerInterceptor interceptor = getInterceptors()[i]; try { interceptor.afterCompletion(request, response, this.handler, ex); } catch (Throwable ex2) { logger.error("HandlerInterceptor.afterCompletion threw exception", ex2); } } } |
DispatcherServlet 默认装配的 HandlerExceptionResolver :
ExceptionHandlerExceptionResolver是处理带有注释@ExceptionHandler(value={Exception.class})异常的
ResponseStatusExceptionResolver是处理带有注释@ResponseStatus(reason="runtionError", value=HttpStatus.NOT_FOUND)
class myRuntimeExceptionClass extends RuntimeException{ 的自定义异常类的
除去这两种以外的 都由默认的异常处理器DefaultHandlerExceptionResolver来处理
<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"; } |
<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"; } |
@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 |
<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.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"; } |
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 "";
} |
org.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"; } |
@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; } |
如果希望对所有异常进行统一处理,可以使用 SimpleMappingExceptionResolver,它将异常类名映射为视图名,即发生异常时使用对应的视图报告异常
<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"; } |
<!-- 配置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; } |
判断请求URI对应的映射
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!