一、過濾器Filter
1.filter的簡介
filter是對客戶端訪問資源的過濾,符合條件放行,不符合條件不放行,並且可以對目 標資源訪問前後進行邏輯處理
2.快速入門
步驟:
1)編寫一個過濾器的類實現Filter介面
2)實現介面中尚未實現的方法(著重實現doFilter方法)
3)在web.xml中進行配置(主要是配置要對哪些資源進行過濾)
(1)建立Filter實現Filter
攔截之後要放行。
package filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; public class FirstFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { // TODO Auto-generated method stub } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 自動攔截請求 System.out.println("filter running......."); // 放行 chain.doFilter(request, response); } @Override public void destroy() { // TODO Auto-generated method stub } }
(2)Web.xml配置一下
<filter> <filter-name>FirstFilter</filter-name> <filter-class>filter.FirstFilter</filter-class> </filter> <filter-mapping> <filter-name>FirstFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
/*代表所有請求,如果不放行,客戶端得不到響應。
3.Filter的API詳解
(1)filter生命週期及其與生命週期相關的方法
Filter介面有三個方法,並且這個三個都是與Filter的生命相關的方法
init(Filterconfig):代表filter物件初始化方法 filter物件建立時執行
doFilter(ServletRequest,ServletResponse,FilterCha):代表filter執行過濾的核心方法,如果某資源在已經被配置到這個filter進行過濾的話,那麼每次訪問這個資源都會執行doFilter方法
destory():代表是filter銷燬方法 當filter物件銷燬時執行該方法
Filter物件的生命週期:
Filter何時建立:伺服器啟動時就建立該filter物件
中間在客戶端訪問過濾器過濾的資源時呼叫doFilter方法
Filter何時銷燬:伺服器關閉時filter銷燬
(2)Filter的API詳解
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方法可以放行該請求
4.Filter的配置
<filter> <filter-name>Filter2</filter-name> <filter-class>filter.Filter2</filter-class> <init-param> <param-name>name</param-name> <param-value>dahua</param-value> </init-param> </filter> <filter-mapping> <filter-name>Filter2</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> </filter-mapping>
也可以直接攔截Servlet(等價於url-pattern /sertvle1)
<filter-mapping> <filter-name>Filter2</filter-name> <servlet-name>servlet</servlet-name> </filter-mapping>
①url-pattern配置時(不用寫工程名字,直接寫路徑)
1)完全匹配 /sertvle1
2)目錄匹配 /aaa/bbb/* ----最多的
/user/*:訪問前臺的資源進入此過濾器
/admin/*:訪問後臺的資源時執行此過濾器
3)副檔名匹配 *.abc *.jsp
注意:url-pattern可以使用servlet-name替代,也可以混用
dispatcher:訪問的方式(瞭解)
REQUEST:預設值,代表直接訪問某個資源時執行filter
轉發攔截一次,重定向2次
FORWARD:轉發時才執行filter
INCLUDE: 包含資源時執行filter
ERROR:發生錯誤時 進行跳轉是執行filter
5.總結Filter的作用?
1)公共程式碼的提取
2)可以對request和response中的方法進行增強(裝飾者模式/動態代理)
3)進行許可權控制
6.總結
1.Filter先寫實現方法,再在web.xml中配置(名字,對映以及攔截的請求)
url-pattern配置時 不寫工程名字
1)完全匹配 /sertvle1
2)目錄匹配 /aaa/bbb/* ----最多的
/user/*:訪問前臺的資源進入此過濾器
/admin/*:訪問後臺的資源時執行此過濾器
3)副檔名匹配 *.abc *.jsp
2.過濾器的執行順序根據你在web.xml中對映的順序執行。
3.可以過濾使用者請求:
package web.filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import daomain.User; public class RequestFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { // TODO Auto-generated method stub } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // TODO Auto-generated method stub HttpServletRequest req =(HttpServletRequest) request; HttpServletResponse res = (HttpServletResponse) response; HttpSession session = req.getSession(); User user = (User) session.getAttribute("user"); if(user==null){ request.getRequestDispatcher("/index.jsp").forward(request, response); } else{ System.out.println(user); } chain.doFilter(request, response); } @Override public void destroy() { // TODO Auto-generated method stub } }
二、設定編碼格式
1.post提交
(1)編寫過濾器程式碼
@Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { request.setCharacterEncoding("utf-8"); chain.doFilter(request, response); }
(2)Web.xml中隊所有請求攔截
(3)後臺直接接受post提交的中文資料
2.get提交
接收前端:
String para = request.getParameter("name"); String para2 = new String(para.getBytes("iso-8859-1"),"utf-8");
向前端傳送
//設定response查詢的碼錶 //response.setCharacterEncoding("UTF-8"); //通過一個頭 Content-Type 告知客戶端使用何種碼錶 //response.setHeader("Content-Type", "text/html;charset=UTF-8"); // 這句與上句等價,開發中只用寫這句,tomcat自動設定第一句 response.setContentType("text/html;charset=UTF-8");
三、裝飾者模式解決亂碼
package filter; import java.io.IOException; import java.io.UnsupportedEncodingException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; 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增強 @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; } }
四、過濾登入的過濾器
<filter> <filter-name>sessionFilter</filter-name> <filter-class>com.FlyPig.util.filter_session</filter-class> </filter> <filter-mapping> <filter-name>sessionFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
filter程式碼如下:起到了過濾登陸介面login.jsp和根路徑以外的過濾
1 package com.FlyPig.util; 2 3 import java.io.IOException; 4 5 import javax.servlet.Filter; 6 import javax.servlet.FilterChain; 7 import javax.servlet.FilterConfig; 8 import javax.servlet.ServletException; 9 import javax.servlet.ServletRequest; 10 import javax.servlet.ServletResponse; 11 import javax.servlet.http.HttpServletRequest; 12 import javax.servlet.http.HttpServletResponse; 13 import javax.servlet.http.HttpSession; 14 15 public class filter_session implements Filter { 16 private String encoding; 17 18 public filter_session() { 19 } 20 21 public void init(FilterConfig filterconfig) throws ServletException { 22 encoding = "utf-8"; 23 } 24 25 public void doFilter(ServletRequest servletrequest, 26 ServletResponse servletresponse, FilterChain filterchain) 27 throws IOException, ServletException { 28 servletrequest.setCharacterEncoding(encoding); 29 servletresponse.setCharacterEncoding(encoding); 30 HttpServletRequest req=(HttpServletRequest)servletrequest; 31 HttpSession session=req.getSession(); 32 HttpServletResponse resp=(HttpServletResponse) servletresponse; 33 34 String url=req.getRequestURI(); 35 System.out.println(url); 36 if(!url.equals("/FlyPig")&&!url.equals("/FlyPig/login.jsp")){ 37 if(session.getAttribute("username")==null||session.getAttribute("username")==""){ 38 resp.sendRedirect("login.jsp"); 39 return ; 40 } 41 } 42 43 44 filterchain.doFilter(servletrequest, servletresponse); 45 } 46 47 public void destroy() { 48 } 49 }
補充:過濾器在請求前可以執行一次,請求後也可以執行:
//前處理 filterchain.doFilter(servletrequest, servletresponse); //後處理
也就是說在請求完成並且頁面載入完成之後會執行後處理,從Java的語法來看放行之後方法沒有retur,所以方法會繼續執行。用於在處理所有請求的一次請求前和請求後處理。