javaWEB学习之filter
JavaWeb三大組件
1. 都需要在web.xml中進行配置
Servlet
Listener
Filter
2. 過濾器
????? 它通過web.xml管理著一大片資源,它會在一組資源(jsp、servlet、.css、.html等等)的前面執行!它當你想要訪問它管理的資源時,那么它就會攔截進行處理.它可以讓請求得到目標資源,也可以不讓請求達到!就好比如門衛.? 只要是對很多的資源進行操作就應該想到filter
?
過濾器如何編寫
1. 寫一個類實現Filter接口
2. 在web.xml中進行配置管理哪些資源
?
1. Filter接口
????public?void?doFilter(ServletRequest?request,?ServletResponseresponse,FilterChain?chain)?throws?IOException,?ServletException{System.out.println("filterstart...");?chain.doFilter(request,response);//放行?System.out.println("filterend...");?}?
void init(FilterConfig)
? * 創建之后,馬上執行;Filter會在服務器啟動時就創建!
void destory()
? * 銷毀之前執行!在服務器關閉時銷毀
void doFilter(ServletRequest,ServletResponse,FilterChain)
? * 每次過濾時都會執行
Filter是單例的!和servlet一樣
?
2. web.xml
<filter>
? <filter-name>xxx</filter-name>
? <filter-class>web.filter.AFitler</fitler-class>
</servlet>
<fitler-mapping>
? <filter-name>xxx</filter-name>
? <url-pattern>/*</url-pattern>
</filter-mapping>
這個配置代表了這個filter管理哪些資源.訪問這些資源時,這個過濾器就會執行doFilter()..
FilterConfig-->與ServletConfig相似
? * 獲取初始化參數:getInitParameter()
? * 獲取過濾器名稱:getFilterName()
? * 獲取appliction:getServletContext()
FilterChain(這個用于放行)
? * doFilter(ServletRequest, ServletResponse):放行!
??? 就相當于調用了目標Servlet的service()方法!
-------------------------------
-------------------------------
多過濾器情況下FilterChain的doFilter()方法:執行目標資源,或是執行下一個過濾器!如果沒有下一個過濾器那么執行的是目標資源,如果有,那么就執行下一個過濾器!
-------------------------------
過濾器的四種攔截方式
? <dispatcher>REQUEST</dispatcher>默認的!攔截直接請求
? <dispatcher>FORWARD</dispatcher>????????????攔截請求轉發
? <dispatcher>INCLUDE</dispatcher>??????????????攔截請求包含??
? <dispatcher>ERROR</dispatcher>????????????????攔截錯誤轉發
在<filter-mapping>中進行配置!
-------------------------------
多個過濾器的執行順序
<filter-mapping>的配置順序決定了過濾器的執行順序!
?
過濾器的應用場景:
執行目標資源之前做預處理工作,例如設置編碼,這種試通常都會放行,只是在目標資源執行之前做一些準備工作;
通過條件判斷是否放行,例如校驗當前用戶是否已經登錄,或者用戶IP是否已經被禁用;
在目標資源執行后,做一些后續的特殊處理工作,例如把目標資源輸出的數據進行處理
?
實例:
統計IP
循環遍歷在ServletContext中的map,其中key是ip地址,value是訪問次數
jsp頁面
<body> <h1>分IP統計訪問次數</h1> <table?align="center"width="50%"?border="1"><tr><th>IP地址</th><th>次數</th></tr> <c:forEach?items="${aplicationScope.ipCountMap}"?var="entry"><tr><td>${entry.key?}</td><td>${entry.value?}</td></tr> </c:forEach></table>?? </body>filter代碼
public?void?init(FilterConfig?fConfig)?throws?ServletException?{context?=?fConfig.getServletContext();Map<String,?Integer>?ipCountMap?=?new?LinkedHashMap<String,?Integer>();context.setAttribute("ipCountMap",?ipCountMap);}public?void?doFilter(ServletRequest?request,?ServletResponseresponse,FilterChain?chain)?throws?IOException,?ServletException{HttpServletRequest?req?=?(HttpServletRequest)?request;String?ip?=?req.getRemoteAddr();Map<String,?Integer>?ipCountMap?=?(Map<String,Integer>)?context.getAttribute("ipCountMap");Integer?count?=?ipCountMap.get(ip);if?(count?==?null)?{count?=?1;}?else?{count?+=?1;}ipCountMap.put(ip,?count);context.setAttribute("ipCountMap",?ipCountMap);chain.doFilter(request,?response);}public?void?destroy()?{} }?
解決全站字符亂碼
亂碼問題:
l? 獲取請求參數中的亂碼問題;
? POST請求:request.setCharacterEncoding(“utf-8”);
? GET請求:newString(request.getParameter(“xxx”).getBytes(“iso-8859-1”), “utf-8”);
l? 響應的亂碼問題:response.setContextType(“text/html;charset=utf-8”)。
處理POST請求簡單,可是處理get請求需要獲取參數,filter獲取所有過濾資源的參數是不可能實現的.這里可以調包request再發給servlet.增強request對象(改變getParamater()方法.讓每次獲取參數時直接解決亂碼問題).
????增強對象的方式有三種:(對a對象進行增強,fun1()方法)
繼承:? AA類繼承a對象的類型:A類,然后重寫fun1()方法,其中重寫的fun1()方法就是被增強的方法。但是,繼承必須要知道a對象的真實類型,然后才能去繼承。如果我們不知道a對象的確切類型,而只知道a對象是IA接口的實現類對象,那么就無法使用繼承來增強a對象了;
裝飾者模式: AA類去實現a對象相同的接口:IA接口,還需要給AA類傳遞a對象,AA類所有方法的實現都是調用a對象相同方法實現,只有fun1()方法需要改變下內容,對fun1()進行增強;
動態代理:和增強者模式比較相似
這里對request對象進行增強是通過繼承request對象的裝飾類,裝飾類是接口的包裝類,但是它不進行任何增強,我們通過繼承它然后重寫需要增強的方法,這樣就不用重寫需要增強的方法了.
?
(增強時一看繼承類,二看有沒有接口的包裝類,三接口的裝飾者模式)
public?class?EncodingFilter?implements?Filter?{public?void?destroy()?{}public?void?doFilter(ServletRequest?request,?ServletResponse?response,FilterChain?chain)?throws?IOException,?ServletException?{//?處理post請求編碼問題request.setCharacterEncoding("utf-8");HttpServletRequest?req?=?(HttpServletRequest)?request;/**?處理GET請求的編碼問題*/ //??String?username?=?request.getParameter("username"); //??username?=?new?String(username.getBytes("ISO-8859-1"),?"UTF-8");/**?調包request*/if(req.getMethod().equals("GET"))?{EncodingRequest?er?=?new?EncodingRequest(req);chain.doFilter(er,?response);}?else?if(req.getMethod().equals("POST"))?{chain.doFilter(request,?response);}}public?void?init(FilterConfig?fConfig)?throws?ServletException?{} }?繼承包裝類增強request
/***?裝飾reqeust*/ public?class?EncodingRequest?extends?HttpServletRequestWrapper?{private?HttpServletRequest?req;public?EncodingRequest(HttpServletRequest?request)?{super(request);this.req?=?request;}public?String?getParameter(String?name)?{String?value?=?req.getParameter(name);?//?處理編碼問題try?{value?=?new?String(value.getBytes("iso-8859-1"),?"utf-8");}?catch?(UnsupportedEncodingException?e)?{throw?new?RuntimeException(e);}?return?value;} }?
轉載于:https://blog.51cto.com/s5650326/1725966
總結
以上是生活随笔為你收集整理的javaWEB学习之filter的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 读博文学Android
- 下一篇: H5无障碍旁白模式使用网页支持