Filter簡介:java
過濾器是執行過濾任務的對象,這些任務是針對對某一資源(servlet 或靜態內容)的請求或來自某一資源的響應執行的,抑或同時針對這二者執行。web
Filter的開發過程:設計模式
1.書寫一個class實現Filter接口服務器
2.將filter註冊到web.xmlsession
Filter的配置app
若是一個訪問路徑中配置了多個FIlter,那麼誰的<filter-mapping>配置在前面誰就先調用。jsp
兩種配置模式ide
(1)url-pattern模式:post
路徑匹配:<url-pattern>/*</url-pattern> 攔截全部訪問項目的請求編碼
後綴名匹配: <url-pattern>*.do</url-pattern> 攔截以".do"結尾的請求路徑的請求
(2)指定攔截Servlet模式:
<servlet-name>AServlet</servlet-name> 按照訪問的Servlet來攔截(不經常使用).
注意:配置方式1和方式2能夠同時使用.
注意:若是某個路徑同時符合模式1和模式2,該FIlter將會被調用兩次
注意: FIlter的路徑配置中, 能夠同時使用兩種配置模式,並每種配置模式還可使用屢次.
Filter的生命週期
init 該方法在服務器啓動時運行. Filter對象隨着服務器 的啓動而建立.
doFIlter 當須要攔截時 該方法運行.
destory 服務器關閉時調用,FIlter對象隨着服務器的關閉而銷燬.
Filter的相關對象
1.Servlet的init方法中也會接收一個ServletConfig對象
1>getInitParameter 得到初始化參數
2>getInitParameterNames 得到初始化參數的鍵們
3>getServletContext 得到ServletContext
4>getServletName (沒用)得到Servlet的配置名稱<servlet-name>
2.FilterConfig
String getFilterName() 得到FIlter註冊的名稱
String getInitParameter(String name) 根據鍵得到FIlter元素中的 鍵值對
Enumeration getInitParameterNames() 得到全部Filter元素中的鍵.
ServletContext getServletContext() 得到ServletContext(application)對象
總結: 得到ServletContext的方法
1>ServletConfig
2>HttpSession
3>PageContext
4>FilterConfig
FilterChain 濾器鏈
FilterChain就是在請求時,服務器會把全部要通過的Filter實例引用交給FilterChain. 咱們在Filter的doFilter方法中能夠拿到該對象.而且調用該對象的doFilter方法(放行),filterchain會去向下找後續要調用的過濾器.若是有就繼續調用下一個過濾器的doFilter方法.若是沒有就執行對應的資源,例如servlet.因此,在開發時使用FilterChain對象的doFilter方法放行.若是想要攔截下來再也不向後執行. 不要調用doFIlter方法.
Filter 的4種過濾方式
<dispatcher></dispatcher>使用該配置來決定Filter的攔截方式.
*REQUEST(默認值) ==> 當正常請求時,Filter會攔截
*FORWARD ==> 在請求轉發時纔會攔截
*INCLUD ==> 請求包含時纔會攔截
*ERROR ==> 轉向錯誤頁面時會攔截
案例:
1,在filter中處理get/post提交時中文參數亂碼問題.
(1). 建立一個Request對象(使用裝飾設計模式裝飾原始request),裝 與參數相關方法,解決get亂碼
package cn.web.filter; import java.io.UnsupportedEncodingException; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; //解決全站中文亂碼問題 public class MyRequest extends HttpServletRequestWrapper implements HttpServletRequest { private HashMap<String, String[]> map2; //裝飾request類 public MyRequest(HttpServletRequest request) { super(request); //調用getParameterMap得到含有亂碼的Map集合 Map<String, String[]> map = request.getParameterMap(); //建立新的map對象 map2= new HashMap<String, String[]>(); //遍歷Map集合 for(Entry<String, String[]> en :map.entrySet()){ //得到key鍵 String key = en.getKey(); //得到value值 String[] values = en.getValue(); //遍歷修改每個鍵對應的全部值亂碼 for(int i=0;i<values.length;i++){ try { values[i] = new String(values[i].getBytes("ISO-8859-1"),"UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } //將解決亂碼後的鍵值對加入新的map集合中 map2.put(key, values); } } //解決單個鍵獲取單個值的亂碼狀況 @Override public String getParameter(String name) { //獲取鍵對應的值 String[] values_01 = map2.get(name); //值不爲空時,才進行編碼修改 if(values_01!=null&&values_01.length>0){ return values_01[0]; } return null; } //解決單個鍵獲取多個值得亂碼狀況 public Map getParameterMap() { // TODO Auto-generated method stub return map2; } @Override public String[] getParameterValues(String name) { return map2.get(name); } }
(2). 建立Filter 並設置其攔截路徑爲/*.
package cn.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; public class EncodingFilter implements Filter { public EncodingFilter() { } public void destroy() { } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //0.解決相應亂碼問題 response.setCharacterEncoding("UTF-8"); //1.使用myRequest裝飾原生request對象 MyRequest myRequest = new MyRequest((HttpServletRequest)request); //2.放行請求與相應 chain.doFilter(myRequest, response); } public void init(FilterConfig fConfig) throws ServletException { } }
2.權限訪問控制,根據url來進行權限控制
三類資源:
全部用戶均可訪問的資源(登陸頁面)
登陸用戶可訪問的頁面
admin用戶能夠訪問的後臺管理頁面
Filter處理流程
1>. 得到 當前請求訪問路徑
2>. 判斷當前訪問的資源是否屬於1類資源
//屬於=>放行
3>.得到session中的登錄標示
//得到不到=>重定向到登錄頁面
4>.判斷用戶訪問是否是2類資源
//是=>放行
5.判斷登錄用戶是不是管理員
//是=>放行
//不是=>提示您沒有權限訪問
LoginServlet.java
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); //得到用戶名 String username = request.getParameter("username"); //將用戶名放入session中 request.getSession().setAttribute("username", username); //重定向到用戶登陸成功頁面 response.sendRedirect(request.getContextPath()+"/success.jsp"); }
PrivilegeFilter.java
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest)request; HttpServletResponse resp = (HttpServletResponse) response; //1.得到當前請求的訪問路徑 String servletPath = req.getServletPath(); System.out.println(servletPath); //2.判斷訪問頁面爲登陸頁面,即爲1類資源,全部用戶都可訪問予以放行 if("/LoginJsp.jsp".equals(servletPath)||"/LoginServlet".equals(servletPath)){ chain.doFilter(request, response); return; } //3.獲取session中的登陸標識 String userName = (String)req.getSession().getAttribute("username"); if(userName==null){ //若是獲取不到,則重定向到登陸頁面 resp.sendRedirect(req.getContextPath()+"/LoginJsp.jsp"); return; } //4.判斷用戶訪問的是否是二類資源,若是是的話,放行 if("/success.jsp".equals(servletPath)||"/noprivilige.jsp".equals(servletPath)){ chain.doFilter(request, response); return; } //5.判斷用戶是否是admin用戶 if("admin".equals(userName)){ //若是是admin用戶,則放行 chain.doFilter(request, response); return ; } else{ //若是不是,返回沒有權限 resp.sendRedirect(req.getContextPath()+"/noprivilige.jsp"); } }
listener簡介:
listener監聽器是一個專門用於對其餘對象身上發生的事件或狀態改變進行監聽和相應處理的對象,當被監視的對象發生狀況時,當即採起相應的行動。監聽器其實就是一個實現特定接口的普通java程序,這個程序專門用於監聽另外一個java對象的方法調用或屬性改變,當被監聽對象發生上述事件後,監聽器某個方法當即被執行。Servlet中的監聽器(8個):
ServletContext對象:
1.監聽application對象的建立與銷燬. ServletContextListener
2.監聽application對象的屬性變化 ServletContextAttributeListener
Session對象:
1.監聽session對象的建立與銷燬. HttpSessionListener
2.監聽session對象的屬性變化 HttpSessionAttributeListener
request對象:
1.監聽request對象的建立與銷燬.ServletRequestListener
2.監聽request對象的屬性變化 ServletRequestAttributeListener
Session對象:(如下兩個監聽器不須要註冊)
1.javaBean與session的綁定與解綁 HttpSessionBindingListener 該接口須要JAVABean實現
2.javaBean在session中的活化(開啓服務器時將硬盤中的session恢復到服務器內存)與鈍化(關閉服務器將session的內容保存到硬盤) HttpSessionActivationListener