Spring攔截器
什么是攔截器
攔截器是Java動(dòng)態(tài)攔截action調(diào)用對(duì)象,它的出現(xiàn)可以使得開(kāi)發(fā)者在action執(zhí)行前后,執(zhí)行自己的代碼邏輯,也可以在一個(gè)動(dòng)作(action)執(zhí)行前阻止其執(zhí)行,應(yīng)用場(chǎng)景很廣泛,譬如:權(quán)限控制,登錄等。
如何實(shí)現(xiàn)攔截器
既然是基于Spring攔截的,那么我們首先是要繼承Spring攔截器的接口,去實(shí)現(xiàn)它提供的方法,從而達(dá)到我們自己要實(shí)現(xiàn)功能的攔截目的。
在HandlerInterceptor接口中定義了 3 個(gè)方法,分別為preHandle()、postHandle()和afterCompletion(),我們就是通過(guò)復(fù)寫(xiě)這 3 個(gè)方法來(lái)對(duì)用戶(hù)的請(qǐng)求進(jìn)行攔截處理的。因此,我們可以通過(guò)直接實(shí)現(xiàn)HandlerInterceptor接口來(lái)實(shí)現(xiàn)攔截器的功能。
preHandle
preHandle(HttpServletRequest request, HttpServletResponse response, Object handle):
該方法在請(qǐng)求處理之前進(jìn)行調(diào)用。一個(gè)方法中可以存在多個(gè)攔截器,而多個(gè)攔截器中的preHandle方法是按照控制器的使用順序而執(zhí)行的!
該方法的返回值是布爾(Boolean)類(lèi)型的,當(dāng)它返回為false時(shí),表示請(qǐng)求結(jié)束,后續(xù)的Interceptor和控制器(Controller)都不會(huì)再執(zhí)行;當(dāng)返回值為true時(shí),就會(huì)繼續(xù)調(diào)用下一個(gè)Interceptor的preHandle方法,如果已經(jīng)是最后一個(gè)Interceptor的時(shí)候,就會(huì)是調(diào)用當(dāng)前請(qǐng)求的控制器中的方法。
postHandle
postHandle(HttpServletRequest request, HttpServletResponse response, Object handle, ModelAndView modelAndView):
通過(guò)
preHandle方法的解釋?zhuān)覀冎肋@個(gè)方法包括后面要說(shuō)到的afterCompletion方法都只能在當(dāng)前所屬的Interceptor的preHandle方法的返回值為true的時(shí)候,才能被調(diào)用。postHandle方法在當(dāng)前請(qǐng)求進(jìn)行處理之后,也就是在控制器中的方法調(diào)用之后執(zhí)行,但是它會(huì)在DispatcherServlet進(jìn)行視圖返回渲染之前被調(diào)用,所以我們可以在這個(gè)方法中對(duì)控制器處理之后的ModelAndView對(duì)象進(jìn)行操作。postHandle方法被調(diào)用的方向跟preHandle是相反的,也就是說(shuō),先聲明的Interceptor的postHandle方法反而會(huì)后執(zhí)行。
afterCompletion
afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex):
也是需要當(dāng)前對(duì)應(yīng)的
Interceptor的preHandle方法的返回值為true時(shí)才會(huì)執(zhí)行。因此,該方法將在整個(gè)請(qǐng)求結(jié)束之后,也就是在DispatcherServlet渲染了對(duì)應(yīng)的視圖之后執(zhí)行,這個(gè)方法的主要作用是用于進(jìn)行資源清理的工作。
實(shí)現(xiàn)一個(gè)攔截器步驟
①編寫(xiě)一個(gè)攔截器,繼承HandlerInterceptor接口并實(shí)現(xiàn)需要實(shí)現(xiàn)的攔截器上述接口任意一種或多個(gè)。
②配置文件繼承WebMvcConfigurer接口,并在類(lèi)開(kāi)始處開(kāi)啟自定義配置支持@EnableWebMvc
③添加一個(gè)bean,實(shí)例化攔截器,以方便注入
④重寫(xiě)WebMvcConfigurer接口中的addInterceptors方法,來(lái)注冊(cè)攔截器
具體實(shí)現(xiàn)攔截器代碼Demo
①Spring配置文件實(shí)例
@Configuration
@EnableWebMvc
@ComponentScan("com.haojishu.demo")
public class MyMvcConfig implements WebMvcConfigurer {
@Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/classes/views/");
viewResolver.setSuffix(".jsp");
viewResolver.setViewClass(JstlView.class);
return viewResolver;
}
public void addInterceptors(InterceptorRegistry registry) {
// TODO Auto-generated method stub
registry.addInterceptor(demoInterceptor());
}
@Bean
public DemoInterceptor demoInterceptor() {
System.out.println("注冊(cè)攔截器");
return new DemoInterceptor();
}
}
②攔截器實(shí)例
public class DemoInterceptor implements HandlerInterceptor {
public DemoInterceptor() {
// TODO Auto-generated constructor stub
System.out.println("構(gòu)造方法執(zhí)行");
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("請(qǐng)求開(kāi)始");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
@Nullable ModelAndView modelAndView) throws Exception {
System.out.println("執(zhí)行完畢后執(zhí)行");
}
}