【Maven+SSM】Springmvc的統一處理之攔截器
阿新 • • 發佈:2019-02-18
前言:
攔截器的使用場景:
程式中的所有請求的共同問題。
1、例如上一篇文章的亂碼問題。本文最後會講到亂碼問題的解決。
2、例如解決許可權驗證的問題。本文最後也會提到。
攔截器與過濾器的區別:
過濾器基於Servlet容器,基於回撥函式,範圍大。
攔截器Interceptor依賴於框架,基於反射,只過濾請求。
正文:
一、寫一個攔截器Interceptor
package interceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; public class TestInterceptor implements HandlerInterceptor{ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("---------preHandle--------"); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("---------postHandle--------"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("---------afterCompletion--------"); } }
其中preHandle返回true說明不中斷請求,否則中斷請求。
二、註冊到SpringMVC。
在springmvc-servlet.xml中配置攔截器
<!-- 註冊攔截器 -->
<mvc:interceptors>
<bean class="interceptor.TestInterceptor"></bean>
</mvc:interceptors>
預設對所有走controller的請求攔截。
三、請求測試:
會按照如下順序列印:
---------preHandle--------
略
---------postHandle--------
略
---------afterCompletion--------
因此,可見,三個方法的呼叫時機。
preHandle請求被處理之前。
postHandle請求被處理之後。
afterCompletion請求結束之後呼叫。
四、修改攔截規則:
僅僅針對部分請求攔截。修改在springmvc-servlet.xml中攔截器如下:
只針對/*.do結尾的路徑攔截。可以測試一下。略。<!-- 註冊攔截器 --> <mvc:interceptors> <mvc:interceptor> <!-- 配置攔截規則 --> <mvc:mapping path="/*.do"/> <bean class="interceptor.TestInterceptor"></bean> </mvc:interceptor> </mvc:interceptors>
五、通過攔截器修改請求跳轉及引數。
跳轉頁面的請求修改,攔截器如下:讓請求處理之後跳轉springmvc指定路徑下的login.jsp,而不是原來的頁面。
package interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
public class TestInterceptor implements HandlerInterceptor{
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("---------preHandle--------");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("---------postHandle--------");
modelAndView.setViewName("/login");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("---------afterCompletion--------");
}
}
此方式僅僅針對原本就是跳轉頁面的請求有效。如果是responseBody的json返回請求則報錯。
同樣可通過修改ModelAndView修改傳遞的引數。例如:
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("---------postHandle--------");
modelAndView.setViewName("/login");
modelAndView.addObject("msg", "我已經被攔截修改了");
}
這樣在頁面中就會獲得msg這個欄位。如果之前有這個欄位,則會被攔截器替換。六、多個攔截器的攔截順序。
<!-- 註冊攔截器 -->
<mvc:interceptors>
<!-- <mvc:interceptor>
配置攔截規則
<mvc:mapping path="/*.do"/>
<bean class="interceptor.TestInterceptor"></bean>
</mvc:interceptor> -->
<bean class="interceptor.TestInterceptor"></bean>
<bean class="interceptor.OtherInterceptor"></bean>
</mvc:interceptors>
執行順序如何?原因,其實就是一個圍繞方法的代理模式。
---------preHandle--------
---------preHandle2--------
略
---------postHandle2--------
---------postHandle--------
略
---------afterCompletion2--------
---------afterCompletion--------
七、攔截器的其他實現方式。
package interceptor;
import org.springframework.ui.ModelMap;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.context.request.WebRequestInterceptor;
public class WebInterceptor implements WebRequestInterceptor{
@Override
public void preHandle(WebRequest request) throws Exception {
// 區別,沒有返回值
}
@Override
public void postHandle(WebRequest request, ModelMap model) throws Exception {
// TODO Auto-generated method stub
}
@Override
public void afterCompletion(WebRequest request, Exception ex) throws Exception {
// TODO Auto-generated method stub
}
}
區別:不能中斷請求。
八、通過攔截器對亂碼問題的解決。
不僅可以如下處理請求的亂碼,也可以處理響應請求的亂碼問題。
package interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
public class TestInterceptor implements HandlerInterceptor{
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("---------preHandle--------");
//處理中文請求亂碼問題
request.setCharacterEncoding("UTF-8");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("---------postHandle--------");
// modelAndView.setViewName("/login");
// modelAndView.addObject("msg", "我已經被攔截修改了");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("---------afterCompletion--------");
}
}
九、攔截器解決許可權驗證的問題。
package interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
public class OtherInterceptor implements HandlerInterceptor{
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("---------preHandle2--------");
if (request.getSession().getAttribute("user")==null) {
//回到登陸頁面
request.getRequestDispatcher("/login.jsp").forward(request, response);;
return false;
}else {
return true;
}
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("---------postHandle2--------");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("---------afterCompletion2--------");
}
}