文章目錄
一、異常處理
1. 異常處理思路
2. 具體步驟
自定義異常類
public class SysException extends Exception {
//異常提示信息
private String message;
@Override
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public SysException(String message) {
this.message = message;
}
}
編寫異常處理器
@Controller
public class SysExceptionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception ex) {
SysException e = null;
//判斷異常類型是否是自定義類型
if(ex instanceof SysException){
//如果拋出的是系統自定義異常則直接轉換
e = (SysException) ex;
}else{
//如果拋出的不是系統自定義異常則重新構造一個系統錯誤異常。
e = new SysException("執行失敗,請聯繫管理員");
}
ModelAndView mv = new ModelAndView();
//存入錯誤提示信息
mv.addObject("errormsg",e.getMessage());
//跳轉到jsp界面
mv.setViewName("error");
return mv;
}
}
模擬異常
<a href="/testException">異常模擬</a>
-------------------------------------------------
@RequestMapping("/testException")
public String testException(){
int i = 10/0; //模擬異常
return "success";
}
error.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h3>錯誤提示界面</h3>
${errormsg}
</body>
</html>
注意 isELIgnored="false"
二、攔截器
1. 攔截器的作用
Spring MVC 的處理器攔截器類似於 Servlet 開發中的過濾器 Filter,用於對處理器進行預處理和後處理。 用戶可以自己定義一些攔截器來實現特定的功能。
談到攔截器,還要向大家提一個詞——攔截器鏈(Interceptor Chain)。攔截器鏈就是將攔截器按一定的順 序聯結成一條鏈。在訪問被攔截的方法或字段時,攔截器鏈中的攔截器就會按其之前定義的順序被調用。
說到這裏,可能大家腦海中有了一個疑問,這不是我們之前學的過濾器嗎?是的它和過濾器是有幾分相似,但是也有區別,接下來我們就來說說他們的區別:
- 過濾器是 servlet 規範中的一部分,任何 java web 工程都可以使用。 攔截器是 SpringMVC 框架自己的,只有使用了 SpringMVC 框架的工程才能用。
- 過濾器在 url-pattern 中配置了 /* 之後,可以對所有要訪問的資源攔截。 攔截器它是隻會攔截訪問的控制器方法,如果訪問的是 jsp,html, css, image 或者 js 是不會進行攔 截的。
攔截器也是 AOP 思想的具體應用。 我們要想自定義攔截器, 要求必須實現:HandlerInterceptor
接口。
2. 攔截器的工作原理
3. 自定義攔截器的步驟
編寫一個普通類實現 HandlerInterceptor 接口
public class HandlerInterceptorDemo1 implements HandlerInterceptor {
/**
* 控制器之前執行
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle 攔截器攔截了");
return true; //如果程序員決定不需要再調用其他的組件去處理請求,則返回 false。
}
/*
* 控制器之後執行
* 攔截器鏈內所有 preHandle 返回 true 纔會調用
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("postHandle 方法執行了");
}
/**
* 最後執行,只有 preHandle 返回 true 才調用
* 可以在該方法中進行一些資源清理的操作。
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion 方法執行了");
}
}
配置攔截器
<!-- 配置攔截器 -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/user/*"/> <!--指定需要進行攔截的url /**/表示攔截所有-->
<mvc:exclude-mapping path=""/> <!--指定不進行攔截的url-->
<bean id="handlerInterceptorDemo1" class="com.itheima.web.interceptor.HandlerInterceptorDemo1"></bean>
</mvc:interceptor>
</mvc:interceptors>
運行結果
4. 多個攔截器的執行順序
按照配置的順序來執行
<!-- 配置攔截器 -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/user/*"/> <!--指定需要進行攔截的url /**/表示攔截所有-->
<mvc:exclude-mapping path=""/> <!--指定不進行攔截的url-->
<bean id="handlerInterceptorDemo1" class="com.itheima.web.interceptor.HandlerInterceptorDemo1"></bean>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean id="handlerInterceptorDemo2" class="com.itheima.web.interceptor.HandlerInterceptorDemo2"></bean>
</mvc:interceptor>
</mvc:interceptors>
preHandle
:按攔截器定義順序調用postHandle
:按攔截器定義逆序調用afterCompletion
:按攔截器定義逆序調用
5. 攔截器方法細節
-
preHandler
:只要配置了都會調用 。如果程序員決定該攔截器對請求進行攔截處理後還要調用其他的攔截器,或者是業務處理器去進行處理,則返回 true。 如果程序員決定不需要再調用其他的組件去處理請求,則返回 false。 -
postHandle
:在攔截器鏈內所有攔截器的 preHandle 返回 true 才調用 -
afterCompletion
:自己的攔截器 preHandle 返回 true 調用
思考: 如果有多個攔截器,這時攔截器 1 的 preHandle 方法返回 true,但是攔截器 2 的 preHandle 方法返 回 false,而此時攔截器 1 的 afterCompletion 方法是否執行?
答案: 攔截器 1 的 afterCompletion 執行,攔截器2的 afterCompletion 不執行, 兩個攔截器的 postHandle 都不執行
👉 👉 👉 原文首發 - 小牛肉的個人博客,歡迎來訪~👈 👈 👈