天天看點

SpringMVC攔截器簡介

什麼是攔截器??

攔截器是指通過統一從浏覽器發往伺服器的請求來完成功能的增強

使用場景:解決請求的共性問題(亂碼問題,權限驗證問題等)

攔截器的工作原理

SpringMVC可以通過配置過濾器來解決亂碼問題

jar包:

SpringMVC攔截器簡介

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

SpringMVC攔截器簡介

攔截器的其他實作方式:

攔截器的類還可以通過實作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依賴于架構容器,基于反射機制,隻過濾請求

繼續閱讀