SpringMVC攔截器
1.攔截器的作用
SpringMVC的處理器攔截器類似于Servlet開發(fā)中的過濾器Filter憎夷,用于對(duì)處理器進(jìn)行預(yù)處理和后處理躬翁。
用戶可以自定義一些攔截器來實(shí)現(xiàn)特定的功能。
攔截器鏈:攔截器鏈就是將攔截器按一定的順序連接成一條鏈查乒。在訪問被攔截的方法或字段時(shí)弥喉,攔截器鏈中的攔截器就會(huì)按其之前定義的順序被調(diào)用。
攔截器和過濾器的區(qū)別:
????過濾器是Servlet規(guī)范中的一部分玛迄,任何java web工程都可以使用由境。
????攔截器是SpringMVC框架自己的,只有使用了SpringMVC框架的工程才可以使用。
????過濾器在url-pattern中配置了/*之后虏杰,可以對(duì)所有要訪問的資源攔截讥蟆。
????攔截器它只會(huì)攔截訪問的控制器方法,如果訪問的是jsp纺阔,html瘸彤,css,image或者是js是不會(huì)進(jìn)行攔截的笛钝。
它也是AOP思想的具體應(yīng)用质况。
我們要想自定義攔截器,要求必須實(shí)現(xiàn):HandlerInterceptor接口玻靡。
2. 自定義攔截器的步驟
????2.1 第一步:編寫一個(gè)普通類實(shí)現(xiàn)HandlerInterception接口
package com.llb.interception;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 自定義攔截器
* Ceate By llb on 2019/8/21
*/
public class MyInterception2 implements HandlerInterceptor {
/**
* 預(yù)處理结榄,controller方法執(zhí)行前
* return true;放行囤捻,執(zhí)行下一個(gè)攔截器臼朗,如果沒有就執(zhí)行controller方法
* return false; 不放行
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("攔截器preHandle方法執(zhí)行了------前2222");
// request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request, response);
return true;
}
/**
* 后處理,controller執(zhí)行方法后執(zhí)行
* @param request
* @param response
* @param handler
* @param modelAndView
* @throws Exception
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("攔截器postHandle方法執(zhí)行了------后2222");
// request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request, response);
}
/**
* 頁面顯示后執(zhí)行
* @param request
* @param response
* @param handler
* @param ex
* @throws Exception
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("攔截器afterCompletion方法執(zhí)行了------最后2222");
}
}
????2.2 配置攔截器
<!--配置攔截器-->
<mvc:interceptors>
<mvc:interceptor>
<!--要攔截的方法:配置一個(gè)即可-->
<mvc:mapping path="/user/*"/>
<!--配置攔截器對(duì)象-->
<bean class="com.llb.interception.MyInterception" />
<!--不攔截的方法:配置一個(gè)即可-->
<!--<mvc:exclude-mapping path=""></mvc:exclude-mapping>-->
</mvc:interceptor>
</mvc:interceptors>
????2.3 控制器方法
/**
* Ceate By llb on 2019/8/21
*/
@Controller
@RequestMapping("/user")
public class UserController {
/**
* 測(cè)試攔截器
* @return
*/
@RequestMapping("/testInterception")
public String testInterception(){
System.out.println("控制器執(zhí)行了");
return "success";
}
}
????2.4 測(cè)試運(yùn)行結(jié)果
3. 攔截器的細(xì)節(jié)
????3.1 攔截器的放行
如果有下一個(gè)攔截器就執(zhí)行下一個(gè)蝎土,如果該攔截器處于攔截器鏈最后一個(gè)视哑,則執(zhí)行控制器中的方法。
????3.2 攔截器中的方法說明
/**
* 預(yù)處理瘟则,controller方法執(zhí)行前
* return true黎炉;放行,執(zhí)行下一個(gè)攔截器醋拧,如果沒有就執(zhí)行controller方法
* return false; 不放行
*
* 如何調(diào)用:
* 按攔截器定義順序調(diào)用
* 何時(shí)調(diào)用:
* 只要配置了都會(huì)調(diào)用
* 有什么用:
* 如果程序員決定該攔截器對(duì)請(qǐng)求攔截處理后還要調(diào)用其他的攔截器慷嗜,或是業(yè)務(wù)處理器進(jìn)行處理,則返回true
* 如果程序員決定不再調(diào)用其他的組件去處理請(qǐng)求丹壕,則返回false
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("攔截器preHandle方法執(zhí)行了------前1111");
// request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request, response);
return true;
}
/**
* 后處理庆械,controller執(zhí)行方法后執(zhí)行
*
* 如何調(diào)用:
* 按攔截器定義逆序調(diào)用
* 何時(shí)調(diào)用:
* 在攔截器鏈內(nèi)所有攔截器返回成功調(diào)用
* 有什么用:
* 在業(yè)務(wù)處理器處理完請(qǐng)求后,但是DispatcherServlet向客戶端返回響應(yīng)前被調(diào)用菌赖。
* 在該方法中對(duì)用戶請(qǐng)求request進(jìn)行處理缭乘。
* @param request
* @param response
* @param handler
* @param modelAndView
* @throws Exception
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("攔截器postHandle方法執(zhí)行了------后1111");
// request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request, response);
}
/**
* 如何調(diào)用:
* 按攔截器定義逆序調(diào)用
* 何時(shí)調(diào)用:
* 只有preHandler返回true才調(diào)用
* 有什么用:
* 在DispatcherServlet完全處理完請(qǐng)求后被調(diào)用
* 可以在該方法中進(jìn)行一些資源清理的操作
* @param request
* @param response
* @param handler
* @param ex
* @throws Exception
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("攔截器afterCompletion方法執(zhí)行了------最后1111");
}
????3.3 攔截器的作用路徑
<!--配置攔截器-->
<mvc:interceptors>
<mvc:interceptor>
<!--要攔截的方法:配置一個(gè)即可:指定攔截的url-->
<mvc:mapping path="/user/*"/>
<!--配置攔截器對(duì)象-->
<bean class="com.llb.interception.MyInterception" />
<!--不攔截的方法:配置一個(gè)即可-->
<!--<mvc:exclude-mapping path=""></mvc:exclude-mapping>-->
</mvc:interceptor>
</mvc:interceptors>
????3.4 多個(gè)攔截器的執(zhí)行順序
按照配置的順序進(jìn)行執(zhí)行的:
4. 多攔截器執(zhí)行測(cè)試
????4.1 springmvc.xml配置:
<!--配置攔截器-->
<mvc:interceptors>
<mvc:interceptor>
<!--要攔截的方法:配置一個(gè)即可-->
<mvc:mapping path="/user/*"/>
<!--配置攔截器對(duì)象-->
<bean class="com.llb.interception.MyInterception" />
<!--不攔截的方法:配置一個(gè)即可-->
<!--<mvc:exclude-mapping path=""></mvc:exclude-mapping>-->
</mvc:interceptor>
<mvc:interceptor>
<!--要攔截的方法:配置一個(gè)即可-->
<mvc:mapping path="/user/*"/>
<!--配置攔截器對(duì)象-->
<bean class="com.llb.interception.MyInterception2" />
<!--不攔截的方法:配置一個(gè)即可-->
<!--<mvc:exclude-mapping path=""></mvc:exclude-mapping>-->
</mvc:interceptor>
</mvc:interceptors>
????4.2 攔截器1的代碼
/**
* 自定義攔截器
* Ceate By llb on 2019/8/21
*/
public class MyInterception implements HandlerInterceptor {
/**
* 預(yù)處理,controller方法執(zhí)行前
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("攔截器preHandle方法執(zhí)行了------前1111");
// request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request, response);
return true;
}
/**
* 后處理琉用,controller執(zhí)行方法后執(zhí)行
* @param request
* @param response
* @param handler
* @param modelAndView
* @throws Exception
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("攔截器postHandle方法執(zhí)行了------后1111");
// request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request, response);
}
/**
* 頁面顯示后執(zhí)行
* @param request
* @param response
* @param handler
* @param ex
* @throws Exception
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("攔截器afterCompletion方法執(zhí)行了------最后1111");
}
}
????4.3 攔截器2的代碼
/**
* 自定義攔截器
* Ceate By llb on 2019/8/21
*/
public class MyInterception2 implements HandlerInterceptor {
/**
* 預(yù)處理堕绩,controller方法執(zhí)行前
* return true;放行邑时,執(zhí)行下一個(gè)攔截器奴紧,如果沒有就執(zhí)行controller方法
* return false; 不放行
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("攔截器preHandle方法執(zhí)行了------前2222");
// request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request, response);
return true;
}
/**
* 后處理,controller執(zhí)行方法后執(zhí)行
* @param request
* @param response
* @param handler
* @param modelAndView
* @throws Exception
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("攔截器postHandle方法執(zhí)行了------后2222");
// request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request, response);
}
/**
* 頁面顯示后執(zhí)行
* @param request
* @param response
* @param handler
* @param ex
* @throws Exception
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("攔截器afterCompletion方法執(zhí)行了------最后2222");
}
}
????4.4 控制器方法
/**
* Ceate By llb on 2019/8/21
*/
@Controller
@RequestMapping("/user")
public class UserController {
/**
* 測(cè)試攔截器
* @return
*/
@RequestMapping("/testInterception")
public String testInterception(){
System.out.println("控制器執(zhí)行了");
return "success";
}
}
????4.5 運(yùn)行結(jié)果
源碼:github