1.SpringMVC的攔截器
SpringMvc處理器攔截器類似於Servlet 開發中的過濾器Filter,用於對處理器進行預處理和後處理。當收到請求時,DispatcherServlet將請求交給處理器映射(HandlerMapping),讓它找出對應請求的HandlerExecutionChain對象。HandlerExecutionChain是一個執行鏈,它包含一個處理該請求的處理器(Handler),同時可以包含若干個對該請求實施攔截的攔截器(HandlerInterceptor)。當HandlerMapping返回HandlerExecutionChain後,DispatcherServlet將請求交給定義在HandlerExecutionChain中的攔截器和處理器一併處理。HandlerExecutionChain是負責處理請求並返回ModelAndView的處理執行鏈,其結構如下圖所示。請求在被Handler執行的前後,鏈中裝配的HandlerInterceptor會實施攔截操作。
攔截器代碼編寫,需要實現HandlerInterceptor接口
public class SpringMvcInterceptor implements HandlerInterceptor{
/**
* 在請求到達Handler之前,先執行這個前置處理方法。當該方法返回false時,請求直接返回,不會傳遞到鏈中
* 下一個攔截器,更不會調用處理器鏈末端的Handler中,只有返回true時請求才向鏈中的下一個處理節點傳遞。
* SpringMvc中的攔截器是鏈式的,可以同時存在多個interceptor,springmvc會根據聲明的前後順序一個
* 接一個的執行,且所有的interceptor中的preHandle方法都會在。
*/
@Override
public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1,
Object arg2) throws Exception {
// TODO Auto-generated method stub
return true;
}
/**
* 在業務處理器處理請求執行完成後,生成視圖之前執行的動作
* 可在modelAndView中加入數據,比如當前時間
*/
@Override
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
Object arg2, ModelAndView arg3) throws Exception {
// TODO Auto-generated method stub
}
/**
* 在DispatcherServlet完全處理完請求後被調用,可用於清理資源、可記錄操作日誌等
* 當有攔截器拋出異常時,會從當前攔截器往回執行所有的攔截器的afterCompletion()
*/
@Override
public void afterCompletion(HttpServletRequest arg0,
HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
// TODO Auto-generated method stub
}
}
位於處理器鏈末端的是一個Handler,DispactherServlet通過HandlerAdapter適配器對Handler進行封裝,並按統一的適配器接口對Handler處理方法進行調用。
<!-- 配置MVC攔截器 -->
<mvc:interceptors>
<!-- 使用bean定義一個interceptor,直接定義在mvc:interceptors根下面interceptor
將攔截所有的請求
-->
<bean class="com.springmvc.assess.interceptor.TimeInterceptor" />
<mvc:interceptor>
<!-- 定義在mvc:interceptor下面的表示對特定的請求才進行攔截 -->
<mvc:mapping path="/**" />
<bean class="com.springmvc.assess.interceptor.SpringMvcInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
可以在SpringMVC.xml中配置多個攔截器,每個攔截器都可以指定一個匹配的映射路徑,以限制攔截器的作用範圍。
- 攔截器例子
<!-- springmvc.xml配置MVC攔截器 -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**" />
<bean class="com.springmvc.assess.interceptor.TimeInterceptor1" />
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/**" />
<bean class="com.springmvc.assess.interceptor.TimeInterceptor2" />
</mvc:interceptor>
</mvc:interceptors>
自定義攔截器
public class TimeInterceptor1 extends HandlerInterceptorAdapter {
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
System.out.println("[TimeInterceptor1_preHandle]"+ "執行開始時間" + sf.format(new Date()));
return true;
}
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("[TimeInterceptor1_postHandle]"+ "執行時間");
}
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("[TimeInterceptor1_afterCompletion]"+ "執行結束時間" + sf.format(new Date()));
}
}
public class TimeInterceptor2 extends HandlerInterceptorAdapter {
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
System.out.println("[TimeInterceptor1_preHandle]"+ "執行開始時間" + sf.format(new Date()));
return true;
}
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("[TimeInterceptor1_postHandle]"+ "執行時間");
}
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("[TimeInterceptor1_afterCompletion]"+ "執行結束時間" + sf.format(new Date()));
}
}
攔截器1放行,攔截器2放行,實現的效果:
將攔截器1放行,攔截器2阻止,實現的效果: