1.什麼是攔截器
攔截器是指通過統一攔截從瀏覽器發往服務端的請求來完成功能的增強。
使用情境:解決請求的共性問題(如:亂碼問題,許可權驗證問題等)
2.攔截器的基本工作原理
springmvc可以通過配置過濾器來解決亂碼問題
攔截器的工作原理和過濾器非常相似
3.實現攔截器
(1)編寫攔截器類實現HandlerInterceptor介面
(2)將攔截器註冊進Springmvc架構中
4.攔截器的方法介紹
(1)preHandle方法,在請求被處理之前進行調用(傳回值:表示我們是否需要將當前的請求攔截下來,返回
false,請求被終止,返回true,將繼續運行,object arg2 表示的是被攔截的請求的目標對象)
(2)postHandle方法,在請求被處理之後調用(可以通過ModelAndView參數來修改顯示的視圖,或修改發往
視圖的方法)
(3)afterCompletion,在請求結束之後才進行調用(做資源的銷毀)
5.攔截器的其他實現方式
(1)攔截器的類還可以通過實現WebRequestInterceptor介面來編寫
(2)想springmvc架構註冊的寫法不變
(3)弊端:preHandle方法沒有傳回值,不能終止請求
6.攔截器和過濾器的區別:
(1)過濾器依賴於Servlet容器,基於回呼函數,過濾的範圍大
(2)攔截器依賴於架構容器,基於反射機制,只過濾請求
7.總結:
(1)攔截器可以處理Web應用中請求的一些通用性問題
(2)共性問題在攔截器中處理,可以減少重複代碼,便於維護
下面,我們就寫一段實現登陸許可權攔截器的代碼吧。
一·編寫一個繼承HandlerInterceptorAdapter的類
package com.xinrui.hospital.action.interceptor;import java.util.Set;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.commons.collections.CollectionUtils;import org.springframework.web.servlet.ModelAndView;import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;import com.xinrui.hospital.bean.Admin;import com.xinrui.hospital.util.AdminUtil;/** * * @ClassName: LoginInterceptor * @Description: 登陸攔截器 * @author 梁志成 * @date 2016年3月27日 下午4:51:53 * */public class LoginInterceptor extends HandlerInterceptorAdapter { // 排除的路徑 private Set<String> excludeUrl; // 包含的路徑 private Set<String> includeUrl; @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { boolean flag = false; // 擷取當前url String url = request.getRequestURI().toString(); String loginUrl = request.getSession().getServletContext() .getContextPath() + "/"; // 以工程名加+"/"結尾的也是登陸請求 if (url.endsWith(loginUrl)) { return true; } // 判斷當前路徑是否包含在攔截器中 flag = is_include(includeUrl, url); // 包含在攔截器中,再判斷是否屬於被排除的系列 if (flag) { flag = false; flag = is_include(excludeUrl, url); } else { flag = true; } // 需要被攔截 if (!flag) { // 判斷目前使用者是否存在 Admin admin = AdminUtil.getCurrentAdmin(); if (admin != null) { flag = true; } else { response.sendRedirect("login.html"); } } return flag; } /** * @Title: is_include * @Description: 查詢是否包含在攔截器中 * @param @param sets * @param @param url * @param @return * @return boolean */ private boolean is_include(Set<String> sets, String url) { boolean is_include = false; if (CollectionUtils.isNotEmpty(sets)) { for (String s : sets) { if (url.contains(s)) { is_include = true; break; } } } return is_include; } public Set<String> getExcludeUrl() { return excludeUrl; } public void setExcludeUrl(Set<String> excludeUrl) { this.excludeUrl = excludeUrl; } public Set<String> getIncludeUrl() { return includeUrl; } public void setIncludeUrl(Set<String> includeUrl) { this.includeUrl = includeUrl; }}
二·在springmvc的設定檔中註冊改攔截器
<mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/*" /> <bean class="com.xinrui.hospital.action.interceptor.LoginInterceptor"> <property name="excludeUrl"> <!-- 登陸請求排除 --> <set> <value>/login.</value> <value>/loginOn.</value> <value>/captcha-image.</value> </set> </property> <property name="includeUrl"> <set> <value>.jsp</value> <value>.do</value> <value>.html</value> </set> </property> </bean> </mvc:interceptor> </mvc:interceptors>
三·編寫一個擷取目前使用者的工具類
package com.xinrui.hospital.util;import javax.servlet.http.HttpServletRequest;import org.springframework.web.context.request.RequestContextHolder;import org.springframework.web.context.request.ServletRequestAttributes;import com.xinrui.hospital.bean.Admin;/** * * @ClassName: AdminUtil * @Description: 擷取當前登入使用者 * @author 梁志成 * @date 2016年3月27日 下午6:49:46 * */public class AdminUtil { public static Admin getCurrentAdmin() { HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder .getRequestAttributes()).getRequest(); return (Admin) request.getSession().getAttribute(Constants.ADMIN); }}
好了,這樣就可以實現登入許可權攔截了,是不是很方便快捷啊。