Filter 即爲過濾,用於在 Servlet 以外對 Request 或者 Response 進行修改。它主要用於對用戶請求進行預處理,也能夠對 HttpServletResponse 進行後處理。使用 Filter 的完整流程: Filter 對用戶請求進行預處理,接着將請求交給 Servlet 進行處理並生成響應,最後 Filter 再 對服務器響應進行後處理。在一個 web 應用中,能夠開發編寫多個 Filter,這些 Filter 組合 起來稱之爲一個 Filter 鏈。css
單個過濾器前端
多個過濾器java
<font color="red">如果一個過濾器鏈:先配置先執行(請求時的執行順序);響應時: 以相反的順序執行。</font>web
在 HttpServletRequest 到達 Servlet 以前,攔截客戶的 HttpServletRequest 。根據須要檢查HttpServletRequest,也能夠修改 HttpServletRequest 頭和數據。 服務器
在HttpServletResponse 到達客戶端以前,攔截 HttpServletResponse。根據須要檢查 HttpServletResponse,也能夠修改 HttpServletResponse頭和數據。session
能夠經過實現一個叫作javax.servlet.Fileter的接口來實現一個過濾器,其中定義了 三個方法,init(), doFilter(), destroy()分別在相應的時機執行。後期觀察生命週期。 app
Filter 的實現只須要兩步: jsp
Step1: 編寫 java 類實現 Filter 接口,並實現其 doFilter 方法。 ide
Step2: 經過@WebFilter註解設置它所能攔截的資源。微服務
@WebFilter("/*") public class Filter01 implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { } @Override public void destroy() { } }
Filter 接口中有一個 doFilter 方法,當開發人員編寫好 Filter,並配置對哪一個 web 資源進行攔截後,Web 服務器每次在調用 web 資源的 service 方法以前,都會先調用一下 filter 的 doFilter 方法。所以能夠達到以下效果:
調用目標資源以前,讓一段代碼執行。
是否調用目標資源(便是否讓用戶訪問 web 資源)。
web 服務器在調用 doFilter 方法時,會傳遞一個 filterChain 對象進來,filterChain 對象是 filter 接口中最重要的一個對象,它提供了一個 doFilter 方法,開發人員能夠根據需求決定 是否調用此方法,調用該方法,則 web 服務器就會調用 web 資源的 service 方法,即 web 資源就會被訪問,不然 web 資源不會被訪問。(本質是放行,調用doFilter方法後,即請求能夠到達資源)
/** * 字符亂碼處理 * 亂碼狀況: Tomcat8及以上版本 Tomcat7及如下版本 POST請求 亂碼,須要處理 亂碼,須要處理 request.setCharacterEncoding("UTF-8"); GET請求 不會亂碼,不須要處理 亂碼,須要處理 new String(request.getParameter("參數名").getBytes("ISO-8859-1"),"UTF-8"); 如何處理: 一、處理POST請求 request.setCharacterEncoding("UTF-8"); 二、處理GET請求且服務器版本在Tomcat8如下的 1> 獲得請求類型 (GET請求) 2> 獲得服務器的版本的信息 3> 判斷是GET請求且Tomcat版本小於8 4> 處理亂碼 new String(request.getParameter("參數名").getBytes("ISO-8859-1"),"UTF-8"); */ @WebFilter("/*") public class AEncodingFilter implements Filter { public AEncodingFilter() { } public void destroy() { } public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain chain) throws IOException, ServletException { // 基於HTTP HttpServletRequest request = (HttpServletRequest) arg0; HttpServletResponse response = (HttpServletResponse) arg1; // 處理請求亂碼亂碼 (處理POST請求) request.setCharacterEncoding("UTF-8"); // 處理GET請求且服務器版本在Tomcat8如下的 String method = request.getMethod(); // 若是是GET請求 if ("GET".equalsIgnoreCase(method)) { // 服務器版本在Tomcat8如下的 Apache Tomcat/8.0.45 String serverInfo = request.getServletContext().getServerInfo(); // 獲得具體的版本號 String versionStr = serverInfo.substring(serverInfo.indexOf("/")+1, serverInfo.indexOf(".")); // 判斷服務器版本是否小於8 if (Integer.parseInt(versionStr) < 8) { // 獲得自定義內部類 (MyWapper繼承了HttpServletRequestWapper對象,而HttpServletRequestWapper對象實現了HttpServletRequest接口,因此MyWapper的本質也是request對象) HttpServletRequest myRequest = new MyWapper(request); // 放行資源 chain.doFilter(myRequest, response); return; } } // 放行資源 chain.doFilter(request, response); } public void init(FilterConfig fConfig) throws ServletException { } /** * 定義內部類,繼承HttpServletRequestWrapper包裝類對象,重寫getParameter()方法 */ class MyWapper extends HttpServletRequestWrapper { // 定義成員變量,提高構造器 中的request對象的範圍 private HttpServletRequest request; public MyWapper(HttpServletRequest request) { super(request); this.request = request; } /** * 重寫getParameter()方法 */ @Override public String getParameter(String name) { String value = request.getParameter(name); if (value != null && !"".equals(value.trim())) { try { // 將默認ISO-8859-1編碼的字符轉換成UTF-8 value = new String(value.getBytes("ISO-8859-1"),"UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } return value; } } }
/** * 非法訪問攔截(當用戶未登陸時,攔截請求到登陸頁面) * 攔截的資源: * 攔截全部資源 /* * 須要被放行的資源: * 不須要登陸便可訪問的資源 * 一、放行指定頁面,不須要登陸能夠訪問的頁面 (例如:登陸頁面、註冊頁面等) * 二、放行靜態資源(例如:css、js、image等資源) * 三、放行指定操做,不須要登陸便可執行的操做(例如:登陸操做、註冊操做等) * 四、登陸狀態放行 (若是存在指定sessuin對象,則爲登陸狀態) */ @WebFilter("/*") public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain chain) throws IOException, ServletException { // 基於HTTP HttpServletRequest request = (HttpServletRequest) arg0; HttpServletResponse response = (HttpServletResponse) arg1; // 獲得請求的路徑 String path = request.getRequestURI(); // 站點名/資源路徑 // 一、放行指定頁面,不須要登陸能夠訪問的頁面 (例如:登陸頁面、註冊頁面等) if (path.contains("/login.jsp") || path.contains("/register.jsp")) { chain.doFilter(request, response); return; } // 二、放行靜態資源(例如:css、js、image等資源) if (path.contains("/js")) { chain.doFilter(request, response); return; } // 三、放行指定操做,不須要登陸便可執行的操做(例如:登陸操做、註冊操做等) if (path.contains("/loginServlet")) { chain.doFilter(request, response); return; } // 四、登陸狀態放行 (若是存在指定sessuin對象,則爲登陸狀態) // 獲得session域對象 String uname = (String) request.getSession().getAttribute("user"); // 若是session域對象不爲空,則爲登陸狀態,放行資源 if (uname != null && !"".equals(uname.trim())) { chain.doFilter(request, response); return; } // 若以上條件均不知足,攔截跳轉到登陸頁面 response.sendRedirect("login.jsp"); return; }
想要更多Java,前端,大數據,微服務等資料<a href="https://i.loli.net/2020/06/22/zbPOtKIqDjo45Mw.png">點我掃碼領取</a>;