什麼是攔截器??
攔截器是指通過統一從浏覽器發往伺服器的請求來完成功能的增強
使用場景:解決請求的共性問題(亂碼問題,權限驗證問題等)
攔截器的工作原理
SpringMVC可以通過配置過濾器來解決亂碼問題
jar包:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiclRnblN0LclHdpZXYyd2LcBzNvwVZ2x2bzNXak9CX90TQNNkRrFlQKBTSvwFbslmZvwFMwQzLcVmepNHdu9mZvwFVywUNMZTY18CX052bm9CX90ERNFzaU9EerNTW240MkZXUYpVd1kmYr50MZV3YyI2cKJDT29GRjBjUIF2LcRHelR3LcJzLctmch1mclRXY39zN5kTOyMDNxETMzcDM3EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
web.xml:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>viewSpace</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>viewSpace</servlet-name>
*.form
</servlet-mapping>
viewSpace-servlet.xml:
<context:component-scanbase-package="com.imooc.test"></context:component-scan>
applicationContext.xml:
<context:annotation-config />
<context:component-scan base-package="com.imooc.test">
<context:exclude-filter type="annotation"
expres sion="org.springframework.stereotype.Controller"/>
</context:component-scan>
@Controller
@RequestMapping("/")
public class TestController {
@RequestMapping("/viewAll")
public ModelAndView viewAll(String name,String pwc){
ModelAndView mv = new ModelAndView();
System.out.println("進入viewAll方法。。。。。");
System.out.println("name="+name);
System.out.println("pwc="+pwc);
mv.setViewName("/hello1.jsp");
return mv;
}
}
login.jsp:
使用者名:<input type="text" name="name"><br/>
密碼:<input type="text" name="pwc"><br/>
<input type="submit" value="登入">
通路:http://localhost:8080/TestSpringMVC1/login.jsp
在使用者和密碼處填寫相關字元,點選登入。頁面跳轉到
http://localhost:8080/TestSpringMVC1/viewAll.form既是hello1.jsp
背景輸出:
進入viewAll方法。。。。。
name=123
pwc=456
但是如果填寫漢字就會亂碼,是以我們在web.xml檔案添加:
<filter>
<filter-name>encoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
亂碼就會得到解決。
攔截器和過濾器的基本原理很類似。
攔截器的實作
.編寫攔截器類實作HandlerInterceptor
.将攔截器注冊進SpringMVC
.配置攔截器的攔截規則
public class Test1Interceptor implementsHandlerInterceptor{
public void afterCompletion(HttpServletRequest arg0,
HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
System.out.println("afterCompletion");
}
public void postHandle(HttpServletRequest arg0,HttpServletResponse arg1,
Object arg2, ModelAndView arg3) throws Exception {
System.out.println("postHandle");
}
public boolean preHandle(HttpServletRequest arg0,HttpServletResponse arg1,
Object arg2) throws Exception {
System.out.println("preHandle");
return true;
}
}
viewSpace-servlet.xml:
<mvc:interceptors>
<mvc:interceptor>
<beanclass="com.imooc.test.interceptor.Test1Interceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
通路填寫名字和密碼:
preHandle
進入viewAll方法。。。。。
name=李四
pwc=123
postHandle
afterCompletion
攔截器的方法介紹:
.preHandle方法,在請求被處理前進行調用
傳回為boolean類型,表示我們是否需要将目前的請求攔截下來,如果傳回false,請求将被終止,如果傳回true請求會繼續運作。
改為false,執行登入操作結果:
隻有preHandle
參數:
HttpServletRequest存儲的是請求的内容
HttpServletResponse存儲的響應的内容
Object arg2 表示的是被攔截的請求的目标對象,既是TestController這個類的執行個體對象
.postHandle方法,在請求被處理之後進行調用
ModelAndView參數可以改變顯示的視圖,或修改發往視圖的方法
在TestController的viewAll方法添加:
mv.addObject("msg","這裡是viewAll的資料!");
在hello1.jsp中添加:
${msg}
執行登入操作:
hello1.jsp中多顯示了一行:這裡是viewAll的資料!
之後在Test1Interceptor的postHandle中添加:
arg3.addObject("msg","這是被攔截器postHandle修改之後的消息!");
執行登入操作:
hello1.jsp中多顯示了一行:這是被攔截器postHandle修改之後的消息!
而沒有在顯示:這裡是viewAll的資料!
arg3.setViewName("/hello2.jsp");這樣在登入操作後會調到hello2.sjp界面
.afterCompletion方法,在請求結束之後進行調用
多個攔截器應用:
複制一份Test1Interceptor,并将輸出進行差別,隻保留輸出語句。
viewSpace-servlet.xml:
<!-- 注冊攔截器 -->
<mvc:interceptors>
<beanclass="com.imooc.test.interceptor.Test1Interceptor"></bean>
<beanclass="com.imooc.test.interceptor.Test2Interceptor"></bean>
</mvc:interceptors>
執行登入結果:
preHandle1
preHandle2
進入viewAll方法。。。。。
name=李四
pwc=123
postHandle2
postHandle1
afterCompletion2
afterCompletion1
攔截器的其他實作方式:
攔截器的類還可以通過實作WebRequestInterceptor接口來編寫,向SpringMVC架構注冊的寫法不變
弊端:preHandle方法沒有傳回值,不能終止請求
public class Test3Interceptor implementsWebRequestInterceptor{
public void afterCompletion(WebRequest arg0, Exceptionarg1)
throws Exception {
}
public void postHandle(WebRequest arg0, ModelMap arg1) throwsException {
}
public void preHandle(WebRequest arg0) throws Exception{
}
}
攔截器的使用場景:
使用原則:處理所有請求的共同問題
1.解決亂碼問題
删除掉web.xml中過濾器的部分
在Test1Interceptor的preHandle方法中添加:
arg0.setCharacterEncoding("utf-8");
可以達到和過濾器一樣的解決亂碼問題的效果。
2.解決權限驗證問題
在Test1Interceptor的preHandle方法中添加:
if(arg0.getSession().getAttribute("user")==null){
arg0.getRequestDispatcher("/login.jsp").forward(arg0,arg1);
return false;
}
執行登入操作時,會跳回到原頁面(login.jsp),背景輸出:preHandle1
攔截器和過濾器的差別:
過濾器Filter依賴于Servlet容器,基于回調函數,過濾範圍大
攔截器Interceptor依賴于架構容器,基于反射機制,隻過濾請求