最後附有網盤鏈接(程序打包+數據庫)
Spring 攔截器
1、定義與應用場景
攔截器是spring中的一個重要概念(類似於Filter過濾器)。他被註冊到spring,攔截指定規則的請求,基於回調機制執行。一般來說,攔截器只會攔截action請求,這一點與過濾器不同。
應用場景:
權限檢查:如是否已經登錄,或則對某些數據具有增刪改查等權限;
日誌記錄:可以記錄請求信息的日誌,以便進行信息監控,信息統計等;
性能監控:慢日誌等。
2、攔截器接口
1.處理器攔截器(HandlerIntercepto):
public interface HandlerInterceptor {
/**
* 預處理回調方法,實現處理器的預處理(如檢查登陸),第三個參數爲響應的處理器,自定義Controller
* 返回值:true表示繼續流程(如調用下一個攔截器或處理器);false表示流程中斷(如登錄檢查失敗),不會繼續調用其他的攔截器或處理器,此時我們需要通過response來產生響應;
*/
boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception;
/**
* 後處理回調方法,實現處理器的後處理(但在渲染視圖之前),此時我們可以通過modelAndView(模型和視圖對象)對模型數據進行處理或對視圖進行處理,modelAndView也可能爲null。
*/
void postHandle(
HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
throws Exception;
/**
* 整個請求處理完畢回調方法,即在視圖渲染完畢時回調,如性能監控中我們可以在此記錄結束時間並輸出消耗時間,還可以進行一些資源清理,類似於try-catch-finally中的finally,但僅調用處理器執行鏈中
*/
void afterCompletion(
HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception;
}
3、攔截流程
攔截器執行順序按照Spring配置文件中定義的順序執行;
首先按照執行順序執行所有攔截器的preHandle()方法【用於預處理等】,如果遇到返回值是false,則不會執行還未執行的攔截器,而是直接倒序執行afterCompletion()方法,如果爲true,則依次執行剩下的攔截器;
如果所有攔截器的preHandle()方法返回值都爲true,則執行相應的控制層接口(controller),如果在該接口中有異常拋出,則和preHandle()方法返回false一樣,不會執行postHandle(),而是直接倒序執行afterCompletion()方法;
如果接口(controller)中業務邏輯執行完成(頁面還未渲染數據),會倒序執行postHandle()方法,渲染完數據後,然後倒序執行afterCompletton()方法。
4、來個流程圖解釋
本次以兩個攔截器更深度地解釋
運行結果
01:04:46.196 [http-nio-8080-exec-2] INFO org.springframework.web.servlet.DispatcherServlet - Completed initialization in 1301 ms
01:04:46.205 [http-nio-8080-exec-2] DEBUG org.springframework.web.servlet.DispatcherServlet - GET "/springmvc/fileUploadPage", parameters={}
01:04:46.210 [http-nio-8080-exec-2] DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped to init.wuji.springboot.mvc.fileupload.action.FileUploadAction#fileUploadPage()
=======MyHandlerInterceptor==========>preHandle
-------------MySecondInterceptor==========preHandle
-------------MySecondInterceptor==========postHandle
=======MyHandlerInterceptor==========>postHandle
01:04:46.233 [http-nio-8080-exec-2] DEBUG org.springframework.web.servlet.view.JstlView - View name 'success', model {}
01:04:46.239 [http-nio-8080-exec-2] DEBUG org.springframework.web.servlet.view.JstlView - Forwarding to [/views/success.jsp]
-------------MySecondInterceptor==========afterCompletion
=======MyHandlerInterceptor==========>afterCompletion
01:04:46.245 [http-nio-8080-exec-2] DEBUG org.springframework.web.servlet.DispatcherServlet - Completed 200 OK
注意順序
上代碼
首先兩個攔截器代碼
第一個文件名:/springmvc/src/main/java/init/wuji/springboot/mvc/interceptor/MyHandlerInterceptor.java
代碼:
package init.wuji.springboot.mvc.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
public class MyHandlerInterceptor implements HandlerInterceptor{
/**
* preHandle方法在handler方法執行之前攔截用戶的請求,如果返回false,表示中斷後續操作,如果返回true,表示向下繼續執行。
*/
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("=======MyHandlerInterceptor==========>preHandle");
return true;
}
/**
* postHandle 該方法在handler方法調用之後,解析視圖之前執行;我們可以通過此方法對請求域中的modle和view進行修改
*/
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
//request.getParameter();
if(modelAndView != null) {
modelAndView.setViewName("success");
}
System.out.println("=======MyHandlerInterceptor==========>postHandle");
}
/**
* afterCompletion 此方法在handler方法執行完畢之後(視圖渲染結束),我們可以通過此方法釋放資源,記錄日誌等操作,及異常處理
*/
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("=======MyHandlerInterceptor==========>afterCompletion");
}
}
第二個攔截器
文件名:/springmvc/src/main/java/init/wuji/springboot/mvc/interceptor/MySecondInterceptor.java
代碼:
package init.wuji.springboot.mvc.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
public class MySecondInterceptor implements HandlerInterceptor{
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("-------------MySecondInterceptor==========preHandle");
return true;
}
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("-------------MySecondInterceptor==========postHandle");
}
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("-------------MySecondInterceptor==========afterCompletion");
}
}
然後是上下文的配置
文件名:/springmvc/src/main/resources/config/applicationContext-mvc.xml
代碼:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
https://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd
">
<context:component-scan base-package="init.wuji.springboot.mvc.*.action"></context:component-scan>
<!--
配置視圖解析器
-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/views/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 上傳文件的最大值, 單位爲:字節 50*1024*1024
-->
<property name="maxUploadSize" value="#{50*1024*1024}" />
</bean>
<mvc:annotation-driven>
<mvc:message-converters>
<!-- register-defaults="true"表示使用默認的消息轉換器 -->
<!-- FastJson(Spring4.2x以上版本設置) -->
<!-- 使用@responsebody註解並且返回值類型爲String時,返回的string字符串帶有雙引號"{'user':'songfs'}",其原因是直接將string類型轉成了json字符串,應該在json解析器之前添加字符串解析器-->
<bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
<!-- FastJsonHttpMessageConverter4 使@ResponseBody支持返回Map<String,Object>等類型,它會自動轉換爲json-->
<!-- 需要返回json時需要配置 produces = "application/json"。不需要再指定utf-8了 -->
<bean id="fastJsonHttpMessageConverter" class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
<!-- 加入支持的媒體類型 -->
<property name="supportedMediaTypes">
<list>
<!-- 這裏順序不能反,一定先寫text/html,不然IE執行AJAX時,返回JSON會出現下載文件 -->
<value>text/html;charset=UTF-8</value>
<value>application/json;charset=UTF-8</value>
<value>application/xml;charset=UTF-8</value>
</list>
</property>
<property name="fastJsonConfig">
<bean class="com.alibaba.fastjson.support.config.FastJsonConfig">
<property name="features">
<list>
<value>AllowArbitraryCommas</value>
<value>AllowUnQuotedFieldNames</value>
<value>DisableCircularReferenceDetect</value>
</list>
</property>
<property name="dateFormat" value="yyyy-MM-dd HH:mm:ss"/>
</bean>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<mvc:interceptors>
<mvc:interceptor>
<!-- mvc:mapping 中配置需要攔截的路徑 -->
<mvc:mapping path="/**"/>
<!--exclude-mapping 中配置需要剔除攔截的路徑 -->
<mvc:exclude-mapping path="/ws/userWsList"/>
<bean class="init.wuji.springboot.mvc.interceptor.MyHandlerInterceptor"></bean>
</mvc:interceptor>
<mvc:interceptor>
<!-- mvc:mapping 中配置需要攔截的路徑 -->
<mvc:mapping path="/userInfoRest/**"/>
<bean class="init.wuji.springboot.mvc.interceptor.MySecondInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
<!--
SSM:spirng springmvc mybatis
spirngboot
儘量不要將業務代碼 與 框架配置信息放到一起
<mvc:view-controller path="/userInfo/userAddInit" view-name="user/add"/>
-->
</beans>
下課
鏈接
鏈接:https://pan.baidu.com/s/1_8Hs6V06GdX7ia5fYV4MlQ
提取碼:7s8u