過濾器Filter
學習目標 |
案例-自動登錄 案例-解決全局的編碼 |
一、過濾器Filter
1.filter的簡介
filter是對客戶端訪問資源的過濾,符合條件放行,不符合條件不放行,並且可以對目標資源訪問前后進行邏輯處理。
2.快速入門
步驟:
1)編寫一個過濾器的類實現Filter接口
2)實現接口中尚未實現的方法(着重實現doFilter方法)
3)在web.xml中進行配置(主要是配置要對哪些資源進行過濾)
3.Filter的API詳解
(1)filter生命周期及其與生命周期相關的方法
Filter接口有三個方法,並且這個三個都是與Filter的生命相關的方法
init(Filterconfig):代表filter對象初始化方法 filter對象創建時執行
doFilter(ServletRequest,ServletResponse,FilterCha):代表filter執行過濾的核心方法,如果某資源在已經被配置到這個filter進行過濾的話,那么每次訪問這個資源都會執行doFilter方法
destory():代表是filter銷毀方法 當filter對象銷毀時執行該方法
Filter對象的生命周期:
Filter何時創建:服務器啟動時就創建該filter對象
Filter何時銷毀:服務器關閉時filter銷毀
(2)Filter的AP詳解
1)init(FilterConfig)
其中參數config代表 該Filter對象的配置信息的對象,內部封裝是該filter的配置信息。
2)destory()方法
filter對象銷毀時執行
3)doFilter方法
doFilter(ServletRequest,ServletResponse,FilterChain)
其中的參數:
ServletRequest/ServletResponse:每次在執行doFilter方法時 web容器負責創建一個request和一個response對象作為doFilter的參數傳遞進來。該request個該response就是在訪問目標資源的service方法時的request和response。
FilterChain:過濾器鏈對象,通過該對象的doFilter方法可以放行該請求
圖filter的訪問流程1:
圖filter的訪問流程2:
4.Filter的配置
注意:flter是按照filter-mapping的順序來執行的
url-pattern配置時
1)完全匹配 /sertvle1
2)目錄匹配 /aaa/bbb/* ----最多的
/user/*:訪問前台的資源進入此過濾器
/admin/*:訪問后台的資源時執行此過濾器
3)擴展名匹配 *.abc *.jsp
注意:url-pattern可以使用servlet-name替代,也可以混用
dispatcher:訪問的方式(了解)
REQUEST:默認值,代表直接訪問某個資源時執行filter
FORWARD:轉發時才執行filter
INCLUDE: 包含資源時執行filter (引用其他資源)
ERROR:發生錯誤時 進行跳轉是執行filter
總結Filter的作用?
1)公共代碼的提取,例如request.setCharacterEncoding(“UTF-8”)
2)可以對request和response中的方法進行增強(裝飾者模式/動態代理)
3)進行權限控制
二、案例
1.自動登錄(核心代碼)
public class AutoLoginFilter implements Filter{ @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse resp = (HttpServletResponse) response; HttpSession session = req.getSession(); //獲得cookie中用戶名和密碼 進行登錄的操作 //定義cookie_username String cookie_username = null; //定義cookie_password String cookie_password = null; //獲得cookie Cookie[] cookies = req.getCookies(); if(cookies!=null){ for(Cookie cookie : cookies){ //獲得名字是cookie_username和cookie_password if("cookie_username".equals(cookie.getName())){ cookie_username = cookie.getValue(); //恢復中文用戶名 cookie_username = URLDecoder.decode(cookie_username, "UTF-8"); } if("cookie_password".equals(cookie.getName())){ cookie_password = cookie.getValue(); } } } //判斷username和password是否是null if(cookie_username!=null&&cookie_password!=null){ //登錄的代碼 UserService service = new UserService(); User user = null; try { user = service.login(cookie_username,cookie_password); } catch (SQLException e) { e.printStackTrace(); } //將登錄的用戶的user對象存到session中 session.setAttribute("user", user); } //放行 chain.doFilter(req, resp); } @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void destroy() { } }
2.解決全局的編碼
1)解決中文登錄名寫入cookie的問題
解決方法:寫入cookie的時候用utf-8編碼,讀出的時候再解碼
//對中文張三進行編碼 String username_code = URLEncoder.encode(username, "UTF-8");// %AE4%kfj //恢復中文用戶名 cookie_username = URLDecoder.decode(cookie_username, "UTF-8");
2)解決全局的編碼問題(核心代碼)
public class EncodingFilter implements Filter{ @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //request.setCharacterEncoding("UTF-8"); //在傳遞request之前對request的getParameter方法進行增強 /* * 裝飾者模式(包裝) * * 1、增強類與被增強的類要實現統一接口 * 2、在增強類中傳入被增強的類 * 3、需要增強的方法重寫 不需要增強的方法調用被增強對象的 * */ //被增強的對象 HttpServletRequest req = (HttpServletRequest) request; //增強對象 EnhanceRequest enhanceRequest = new EnhanceRequest(req); chain.doFilter(enhanceRequest, response); } @Override public void destroy() { } @Override public void init(FilterConfig filterConfig) throws ServletException { } } class EnhanceRequest extends HttpServletRequestWrapper{ private HttpServletRequest request; public EnhanceRequest(HttpServletRequest request) { super(request); this.request = request; } //對getParaameter增強 //注意request中還有類似getParaameter的方法, //這些方法獲取還是亂碼,所以都建議進行重寫 @Override public String getParameter(String name) { String parameter = request.getParameter(name);//亂碼 try { parameter = new String(parameter.getBytes("iso8859-1"),"UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return parameter; } }