在報名系統中,登陸的有兩類用戶,後臺管理員和報名參與者,而他們都有些操做必須登陸才能執行,傳統的Java Web應用中使用過濾器對指定的路徑進行過濾。web
下面攔截管理員,定義登陸過濾器AuthorLoginFilter
:設計模式
/** * 管理員的登陸過濾器 */ public class ManagerLoginFilter implements Filter { /** 白名單:從web.xml中讀取配置 */ protected Set<String> whiteList = new HashSet<>(); /** * 過濾動做 */ public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { //1. 獲得應用的uri if(!whiteList.contains(uri)) { //2. 不在白名單的路徑(須要過濾的) //3. 獲取session中的值? if( author == null) { //4. 未登陸或登陸超時,設置提示信息,重定向到指定路徑? return; } } chain.doFilter(req, resp); } .... }
web.xml中使用過濾器:session
<filter> <description>管理員登陸過濾</description> <filter-name>managerLoginFilter</filter-name> <filter-class>web.filter.ManagerLoginFilter</filter-class> <init-param> <!-- 登陸頁面和登陸動做 --> <param-name>whiteList</param-name> <param-value> /manage/login.do;/manage/; </param-value> </init-param> </filter> <filter-mapping> <filter-name>managerLoginFilter</filter-name> <url-pattern>/manage/*</url-pattern> </filter-mapping>
如今定義UserLoginFilter
過濾,攔截活動參與者須要登陸才能執行的URL。因而COPY上面的代碼,改改!!!app
doFilter(...) { ... // 修改第3步中得到session中的key值: session.getAttribute("CURRENT_USER"); // 修改第4步中的重定向URL }
But問題來了????,有沒有發覺代碼和處理流程驚人的類似,除了上面須要修改的地方。ide
因而我使用模版方法重構, 定義一個抽象公共的父過濾器LogFilter
:this
/** * 抽象的登陸過濾器 * 利用模版設計模式,實現封裝 * @author * */ public abstract class LoginFilter implements Filter { protected Set<String> whiteList = new HashSet<>(); /** * 對應第3步:獲取不一樣類型的登陸對象 * @param session * @return */ protected abstract Object getLoginObject(HttpSession session); /** * 對應第4步:得到重定向路徑 * @param request * @return */ protected abstract String getRedirectPath(HttpServletRequest request); public void destroy() { } public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) resp; HttpSession session = request.getSession(); // 第1步:獲得出去應用名的uri String uri = request.getRequestURI(); String contextPath = request.getContextPath(); if(uri.startsWith( contextPath )) { uri = uri.replaceFirst(contextPath,""); } // 第2步:攔截不在白名單中,且未登陸的請求 if(!whiteList.contains(uri)) { // 第3步:鉤子方法,利用多態特效,調用具體實現的方法 Object targetObject= getLoginObject(session); if(targetObject == null) { session.setAttribute("message", "登陸超時,從新登陸"); // 第4步:鉤子方法,利用多態特性,調用具體的方法實現 response.sendRedirect( getRedirectPath(request)); return; } } chain.doFilter(req, resp); } public void init(FilterConfig config) throws ServletException { String configWhiteData = config.getInitParameter("whiteList"); // 有配置參數 if( !StringUtil.isBlank(configWhiteData) ) { String[] whites = configWhiteData.split(";"); for (String white : whites) { this.whiteList.add(white.trim()); } } } }
/** * 管理員登陸過濾器 * @author * */ public class ManagerLoginFilter extends LoginFilter{ @Override protected Object getLoginObject(HttpSession session) { return session.getAttribute("CURRENT_MANAGER"); } @Override protected String getRedirectPath(HttpServletRequest request) { return request.getContextPath() + "/manage/login.do"; } }
/** * 參與者(用戶)登陸過濾器 * @author * */ public class UserLoginFilter extends LoginFilter{ @Override protected Object getLoginObject(HttpSession session) { return session.getAttribute("CURRENT_USER"); } @Override protected String getRedirectPath(HttpServletRequest request) { return request.getContextPath() + "/index.do"; } }
<filter> <description>管理員登陸過濾</description> <filter-name>managerLoginFilter</filter-name> <filter-class>web.filter.ManagerLoginFilter</filter-class> <init-param> <param-name>whiteList</param-name> <param-value> /manage/login.do;/manage/; </param-value> </init-param> </filter> <filter-mapping> <filter-name>managerLoginFilter</filter-name> <url-pattern>/manage/*</url-pattern> </filter-mapping> <filter> <description>參與者登陸過濾</description> <filter-name>userLoginFilter</filter-name> <filter-class>web.filter.UserLoginFilter</filter-class> <init-param> <param-name>whiteList</param-name> <param-value></param-value> </init-param> </filter> <filter-mapping> <filter-name>userLoginFilter</filter-name> <url-pattern>/user/*</url-pattern> </filter-mapping>
對於某一類問題,具備相同的解決步驟,可是每一步具體的實現可能不一致,可能這個時候就能夠使用模版方法。url
那麼這個問題可否用策略模式解決了????不能設計