<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                http://www.cnblogs.com/javawebsoa/p/3228858.html 1、Filter簡介 (1)Filter也稱之為過濾器,它是Servlet技術中最實用的技術,WEB開發人員通過Filter技術,對web服務器管理的所有web資源:例如Jsp,?Servlet,?靜態圖片文件或靜態?html?文件等進行攔截,從而實現一些特殊的功能。例如實現URL級別的權限訪問控制、過濾敏感詞匯、壓縮響應信息等一些高級功能。 (2)Servlet?API中提供了一個Filter接口,開發web應用時,如果編寫的Java類實現了這個接口,則把這個java類稱之為過濾器Filter。通過Filter技術,開發人員可以實現用戶在訪問某個目標資源之前,對訪問的請求和響應進行攔截,如下所示: 2、Filter是如何實現攔截的? Filter接口中有一個doFilter方法,當開發人員編寫好Filter,并配置對哪個web資源(攔截url)進行攔截后,WEB服務器每次在調用web資源之前,都會先調用一下filter的doFilter方法,因此,在該方法內編寫代碼可達到如下目的: 調用目標資源之前,讓一段代碼執行 是否調用目標資源(即是否讓用戶訪問web資源)。 web服務器在調用doFilter方法時,會傳遞一個filterChain對象進來,filterChain對象是filter接口中最重要的一個對象,它也提供了一個doFilter方法,開發人員可以根據需求決定是否調用此方法,調用該方法,則web服務器就會調用web資源的service方法,即web資源就會被訪問,否則web資源不會被訪問。 調用目標資源之后,讓一段代碼執行 3、Filter開發入門 (1)Filter開發分為二個步驟: 編寫java類實現Filter接口,并實現(三個方法)其doFilter方法。 在?web.xml?文件中使用和元素對編寫的filter類進行注冊,并設置它所能攔截的資源。 (2)Filter鏈?---? 在一個web應用中,可以開發編寫多個Filter,這些Filter組合起來稱之為一個Filter鏈。 web服務器根據Filter在web.xml文件中的注冊順序,決定先調用哪個Filter,當第一個Filter的doFilter方法被調用時,web服務器會創建一個代表Filter鏈的FilterChain對象傳遞給該方法。在doFilter方法中,開發人員如果調用了FilterChain對象的doFilter方法,則web服務器會檢查FilterChain對象中是否還有filter,如果有,則調用第2個filter,如果沒有,則調用目標資源。 Filter鏈實驗(查看filterChain?API文檔) 4、Filter的生命周期 (1)init(FilterConfig?filterConfig)throws?ServletException: 和我們編寫的Servlet程序一樣,Filter的創建和銷毀由WEB服務器負責。?web?應用程序啟動時,web?服務器將創建Filter?的實例對象,并調用其init方法進行初始化(注:filter對象只會創建一次,init方法也只會執行一次。示例?) 開發人員通過init方法的參數,可獲得代表當前filter配置信息的FilterConfig對象。 (2)doFilter(ServletRequest,ServletResponse,FilterChain) 每次filter進行攔截都會執行 在實際開發中方法中參數request和response通常轉換為HttpServletRequest和HttpServletResponse類型進行操作 (3)destroy(): 在Web容器卸載?Filter?對象之前被調用。 package?com.itheima.filter; import?java.io.IOException; import?java.util.Enumeration; 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?com.sun.net.httpserver.Filter.Chain; public?class?Filter1?implements?Filter?{ public?Filter1()?{ System.out.println("Filter被創建出來了。。。"); } public?void?destroy()?{ System.out.println("destory......"); } public?void?doFilter(ServletRequest?request,?ServletResponse?response, FilterChain?chain)?throws?IOException,?ServletException?{ System.out.println("dofilter...."); chain.doFilter(request,?response); } public?void?init(FilterConfig?filterConfig)?throws?ServletException?{ System.out.println("init....."); String?value1?=?filterConfig.getInitParameter("param1"); System.out.println(value1); Enumeration?enumeration?=filterConfig.getInitParameterNames(); while(enumeration.hasMoreElements()){ String?name?=?(String)?enumeration.nextElement(); String?value?=?filterConfig.getInitParameter(name); System.out.println(name+":"+value); } filterConfig.getServletContext(); } } ?5、FilterConfig接口 (1)用戶在配置filter時,可以使用為filter配置一些初始化參數,當web容器實例化Filter對象,調用其init方法時,會把封裝了filter初始化參數的filterConfig對象傳遞進來。因此開發人員在編寫filter時,通過filterConfig對象的方法,就可獲得: String?getFilterName():得到filter的名稱。 String?getInitParameter(String?name):?返回在部署描述中指定名稱的初始化參數的值。如果不存在返回null. Enumeration?getInitParameterNames():返回過濾器的所有初始化參數的名字的枚舉集合。 public?ServletContext?getServletContext():返回Servlet上下文對象的引用。 (2)FilterConfig?提供參數,是Filter類私有參數,Filter2的初始化參數,不能在Filter1?中進行獲取? (3)?配置全局參數,?進行配置,通過ServletContext?獲得? (4)實驗:得到filter配置信息 6、注冊Filter ??????testFitler ?????org.test.TestFiter ????? ?word_file ?/WEB-INF/word.txt ????? 用于為過濾器指定一個名字,該元素的內容不能為空。 元素用于指定過濾器的完整的限定類名。 元素用于為過濾器指定初始化參數,它的子元素指定參數的名字,指定參數的值。在過濾器中,可以使用FilterConfig接口對象來訪問初始化參數。 7、映射Filter 元素用于設置一個?Filter?所負責攔截的資源。一個Filter攔截的資源可通過兩種方式來指定:Servlet?名稱和資源訪問的請求路徑 (1)子元素用于設置filter的注冊名稱。該值必須是在元素中聲明過的過濾器的名字 (2)設置?filter?所攔截的請求路徑(過濾器關聯的URL樣式) (3)指定過濾器所攔截的Servlet名稱。 (4)指定過濾器所攔截的資源被?Servlet?容器調用的方式,可以是REQUEST,INCLUDE,FORWARD和ERROR之一,默認REQUEST。用戶可以設置多個?子元素用來指定?Filter?對資源的多種調用方式進行攔截。 (5)?過濾器攔截配置 如果連接目標資源是一個Servlet,可以選擇url和servlet名稱兩種配置方式? 攔截/hello是Servlet?路徑?--> /hello 攔截Servlet?還可以通過Servlet?名稱進行攔截?--> HelloServlet (6)url-pattern?和?Servlet中路徑寫法一樣,有三種?:?完全匹配、目錄匹配、擴展名匹配 (7)指定過濾器所攔截的資源被?Servlet?容器調用的方式 容器調用服務器端資源?有四種方式? REQUEST、FORWARD、INCLUDE、ERROR 8、映射Filter的多種方式 ?子元素可以設置的值及其意義: REQUEST:當用戶直接訪問頁面時,Web容器將會調用過濾器。如果目標資源是通過RequestDispatcher的include()或forward()方法訪問時,那么該過濾器就不會被調用。 INCLUDE:如果目標資源是通過RequestDispatcher的include()方法訪問時,那么該過濾器將被調用。除此之外,該過濾器不會被調用。 FORWARD:如果目標資源是通過RequestDispatcher的forward()方法訪問時,那么該過濾器將被調用,除此之外,該過濾器不會被調用。 ERROR:如果目標資源是通過聲明式異常處理機制調用時,那么該過濾器將被調用。除此之外,過濾器不會被調用 9、映射Filter示例 ?????testFilter ????/test.jsp ????testFilter ???/index.jsp ???REQUEST ???FORWARD 10、Filter常見應用 (1)統一全站字符編碼的過濾器 通過配置參數encoding指明使用何種字符編碼,以處理Html?Form請求參數的中文問題 案例:編寫jsp?輸入用戶名,在Servlet中獲取用戶名,將用戶名輸出到瀏覽器上? 處理請求post亂碼代碼 request.setCharacterEncoding("utf-8"); 設置響應編碼集代碼 response.setContentType("text/html;charset=utf-8"); 經常會使用,而過濾器可以在目標資源之前執行,將很多程序中處理亂碼公共代碼,提取到過濾器中?,以后程序中不需要處理編碼問題了? package?com.itheima.filter; import?java.io.IOException; import?java.io.UnsupportedEncodingException; import?java.util.Map; 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?{ private?FilterConfig?config?=?null; public?void?destroy()?{ } /** ?*?全站亂碼解決 ?*/ public?void?doFilter(ServletRequest?request,?ServletResponse?response, FilterChain?chain)?throws?IOException,?ServletException?{ HttpServletRequest?req?=?(HttpServletRequest)?request; chain.doFilter(new?MyRequest(req),?response); } class?MyRequest?extends?HttpServletRequestWrapper?{ private?HttpServletRequest?request?=?null; private?boolean?isEncode?=?false; public?MyRequest(HttpServletRequest?request)?{ super(request); this.request?=?request; } @Override public?Map?getParameterMap()?{ if?(request.getMethod().equalsIgnoreCase("post"))?{ try?{ request.setCharacterEncoding(config.getInitParameter("encode")); return?request.getParameterMap(); }?catch?(UnsupportedEncodingException?e)?{ e.printStackTrace(); } }?else?if?(request.getMethod().equalsIgnoreCase("get"))?{ try?{ Map?map?=?request.getParameterMap(); if(!isEncode){ for?(String?key?:?map.keySet())?{ String?[]?vs?=?map.get(key); for(int?i=0;i<vs.length;i++){ String?v?=?vs[i]; v?=?new?String(v.getBytes("iso8859-1"),?config.getInitParameter("encode")); vs[i]?=?v; } } isEncode?=?true; } return?map; }?catch?(Exception?e)?{ e.printStackTrace(); } } return?super.getParameterMap(); } @Override public?String[]?getParameterValues(String?name)?{ if(getParameterMap().get(name)==null)return?null; return?(String[])getParameterMap().get(name); } @Override public?String?getParameter(String?name)?{ if(getParameterMap().get(name)==null)return?null; return?((String[])getParameterMap().get(name))[0]; } } public?void?init(FilterConfig?filterConfig)?throws?ServletException?{ this.config?=?filterConfig; } } package?com.itheima.web; import?java.io.IOException; import?java.util.Map; import?javax.servlet.ServletException; import?javax.servlet.http.HttpServlet; import?javax.servlet.http.HttpServletRequest; import?javax.servlet.http.HttpServletResponse; public?class?EncodeTestServlet?extends?HttpServlet?{ public?void?doGet(HttpServletRequest?request,?HttpServletResponse?response) throws?ServletException,?IOException?{ String?vs?=?request.getParameterValues("username")[0]; System.out.println(vs); String?value?=?request.getParameter("username"); System.out.println(value); } public?void?doPost(HttpServletRequest?request,?HttpServletResponse?response) throws?ServletException,?IOException?{ doGet(request,?response); } } filter> filter-name>encodefilter-name> filter-class>com.itheima.filter.EncodingFilterfilter-class> init-param> param-name>encodeparam-name> param-value>utf-8param-value> init-param> filter> filter-mapping> filter-name>encodefilter-name> url-pattern>/*url-pattern> filter-mapping> (2)禁止瀏覽器緩存所有動態頁面的過濾器: 有?3?個?HTTP?響應頭字段都可以禁止瀏覽器緩存當前頁面,它們在?Servlet?中的示例代碼如下: response.setDateHeader("Expires",-1); response.setHeader("Cache-Control","no-cache");? response.setHeader("Pragma","no-cache");? 并不是所有的瀏覽器都能完全支持上面的三個響應頭,因此最好是同時使用上面的三個響應頭。 Expires數據頭:值為GMT時間值,為-1指瀏覽器不要緩存頁面 Cache-Control響應頭有兩個常用值:? no-cache指瀏覽器不要緩存當前頁面。 max-age:xxx指瀏覽器緩存頁面xxx秒。 package?com.itheima.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.HttpServletResponse; public?class?NoChachFilter?implements?Filter?{ public?void?destroy()?{ //?TODO?Auto-generated?method?stub } public?void?doFilter(ServletRequest?request,?ServletResponse?response, FilterChain?chain)?throws?IOException,?ServletException?{ HttpServletResponse?resp?=?(HttpServletResponse)?response; ??resp.setDateHeader("Expires",-1); ??resp.setHeader("Cache-Control","no-cache"); ??resp.setHeader("Pragma","no-cache"); chain.doFilter(request,?response); } public?void?init(FilterConfig?filterConfig)?throws?ServletException?{ //?TODO?Auto-generated?method?stub } } nocach com.itheima.filter.NoChachFilter nocach *.jsp (3)控制瀏覽器緩存頁面中的靜態資源的過濾器: 場景:有些動態頁面中引用了一些圖片或css文件以修飾頁面效果,這些圖片和css文件經常是不變化的,所以為減輕服務器的壓力,可以使用filter控制瀏覽器緩存這些文件,以提升服務器的性能。 Tomcat緩存策略? 對于服務器端經常不變化文件,設置客戶端緩存時間,在客戶端資源緩存時間到期之前,就不會去訪問服務器獲取該資源?--------?比tomcat內置緩存策略更優手段? *?減少服務器請求次數,提升性能? 設置靜態資源緩存時間,需要設置?Expires?過期時間?,在客戶端資源沒有過期之前,不會產生對該資源的請求的? *?設置Expires?通常使用?response.setDateHeader?進行設置?設置毫秒值? package?com.itheima.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.HttpServletResponse; public?class?CacheFilter?implements?Filter?{ public?void?destroy()?{ //?TODO?Auto-generated?method?stub } public?void?doFilter(ServletRequest?request,?ServletResponse?response, FilterChain?chain)?throws?IOException,?ServletException?{ HttpServletResponse?resp?=?(HttpServletResponse)?response; resp.setDateHeader("Expires",?System.currentTimeMillis()+3600l*24*30*1000); chain.doFilter(request,?response); } public?void?init(FilterConfig?filterConfig)?throws?ServletException?{ //?TODO?Auto-generated?method?stub } } cache com.itheima.filter.CacheFilter cache *.jpg *.gif *.png REQUEST (4)實現用戶自動登陸的過濾器 在用戶登陸成功后,以cookis形式發送用戶名、密碼給客戶端 編寫一個過濾器,filter方法中檢查cookie中是否帶有用戶名、密碼信息,如果存在則調用業務層登陸方法,登陸成功后則向session中存入user對象(即用戶登陸標記),以實現程序完成自動登陸。 在訪問一個站點,登陸時勾選自動登陸(三個月內不用登陸),操作系統后,關閉瀏覽器;過幾天再次訪問該站點時,直接進行登陸后狀態? 在數據庫中創建?user表 create?table?user?( ???id?int?primary?key?auto_increment, ???username?varchar(20), ???password?varchar(40), ???role?varchar(10) ); insert?into?user?values(null,'admin','123','admin'); insert?into?user?values(null,'aaa','123','user'); insert?into?user?values(null,'bbb','123','user'); 自動登陸?:未登錄、存在自動登陸信息、自動登陸信息正確? 在用戶完成登陸后,勾選自動登陸復選框,服務器端將用戶名和密碼?以Cookie形式,保存在客戶端?。當用戶下次訪問該站點,AutoLoginFilter?過濾器從Cookie中獲取?自動登陸信息? 1、判斷用戶是否已經登陸,如果已經登陸,沒有自動登陸的必要 2、判斷Cookie中是否含有自動登陸信息?,如果沒有,無法完成自動登陸 3、使用cookie用戶名和密碼?完成自動登陸? ?page?language="java"?import="java.util.*"?pageEncoding="utf-8"%> DOCTYPE?HTML?PUBLIC?"-//W3C//DTD?HTML?4.01?Transitional//EN"> html> ??head> ??head> ??body> ???form?action="${pageContext.request.contextPath?}/servlet/LoginServlet2"?method="post"> ?? 用戶名input?type="text"?name="username"/> ?? 密碼input?type="text"?name="password"/> ???input?type="checkbox"?name="autoLogin"?value="true"?/>一個月內自動登錄 ???input?type="submit"?value="登錄"/> ???form> ??body> html> package?com.itheima.autologin; import?java.io.IOException; import?javax.servlet.ServletException; import?javax.servlet.http.Cookie; import?javax.servlet.http.HttpServlet; import?javax.servlet.http.HttpServletRequest; import?javax.servlet.http.HttpServletResponse; import?org.apache.commons.dbutils.QueryRunner; import?org.apache.commons.dbutils.handlers.BeanHandler; import?com.itheima.domain.User; import?com.itheima.util.DaoUtil; import?com.itheima.util.MD5Util; public?class?LoginServlet2?extends?HttpServlet?{ public?void?doGet(HttpServletRequest?request,?HttpServletResponse?response) throws?ServletException,?IOException?{ try{ //1.校驗用戶名密碼是否正確 QueryRunner?runner?=?new?QueryRunner(DaoUtil.getSource()); User?user?=?runner.query("select?*?from?user?where?username=??and?password=?",?new?BeanHandler(User.class),request.getParameter("username"),MD5Util.md5(request.getParameter("password"))); if(user?==?null){ request.setAttribute("msg",?"用戶名密碼不正確!!"); request.getRequestDispatcher("/login.jsp").forward(request,?response); return; }else{ //用戶名密碼都正確,在session域中保存用戶的登錄狀態 request.getSession().setAttribute("user",?user); //如果勾選過一個月內自動登錄,發送cookie信息給瀏覽器,使瀏覽器保存用戶名密碼一個月 if(request.getParameter("autoLogin")!=null){ Cookie?cookie?=?new?Cookie("autologin",user.getUsername()+":"+user.getPassword()); cookie.setMaxAge(3600*24*30); cookie.setPath(request.getContextPath()); response.addCookie(cookie); } response.sendRedirect(request.getContextPath()+"/autologin/homepage.jsp"); } }catch?(Exception?e)?{ e.printStackTrace(); } } public?void?doPost(HttpServletRequest?request,?HttpServletResponse?response) throws?ServletException,?IOException?{ doGet(request,?response); } } ?page?language="java"?import="java.util.*"?pageEncoding="utf-8"%> ?taglib?uri="http://java.sun.com/jsp/jstl/core"?prefix="c"?%> DOCTYPE?HTML?PUBLIC?"-//W3C//DTD?HTML?4.01?Transitional//EN"> html> ??head> ??head> ??body> ???c:if?test="${sessionScope.user?==?null}"> ?? 歡迎光臨游客!a?href="${pageContext.request.contextPath?}/autologin/login.jsp">登錄a> ???c:if> ???c:if?test="${sessionScope.user?!=?null}"> ?? 歡迎回來 ???c:if> ??body> html> package?com.itheima.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.Cookie; import?javax.servlet.http.HttpServletRequest; import?org.apache.commons.dbutils.QueryRunner; import?org.apache.commons.dbutils.handlers.BeanHandler; import?com.itheima.domain.User; import?com.itheima.util.DaoUtil; public?class?AutoLoginFilter?implements?Filter?{ public?void?destroy()?{ } public?void?doFilter(ServletRequest?request,?ServletResponse?response, FilterChain?chain)?throws?IOException,?ServletException?{ HttpServletRequest?req?=?(HttpServletRequest)?request; //1.檢查用戶是否已經登錄 if(req.getSession(false)?==?null?||?req.getSession().getAttribute("user")==null){ //2.如果用戶沒有登錄過,則檢查是否帶了autologincookie Cookie?[]?cs?=?req.getCookies(); Cookie?findc?=?null; if(cs!=null){ for(Cookie?c?:?cs){ if(c.getName().equals("autologin")){ findc?=?c; break; } } } if(findc?!=?null){ //3.如果有autologin?cookie,獲取cookie的值,檢查用戶名密碼是否正確 String?username?=?findc.getValue().split(":")[0]; String?password?=?findc.getValue().split(":")[1]; //4.如果用戶名密碼都正確,則自動登錄一把 try{ QueryRunner?runner?=?new?QueryRunner(DaoUtil.getSource()); User?user?=?runner.query("select?*?from?user?where?username=??and?password=?",?new?BeanHandler(User.class),username,password); if(user!=null){ req.getSession().setAttribute("user",?user); } }catch?(Exception?e)?{ e.printStackTrace(); } } } //5.放行資源 chain.doFilter(request,?response); } public?void?init(FilterConfig?filterConfig)?throws?ServletException?{ //?TODO?Auto-generated?method?stub } } autologinFilter com.itheima.filter.AutoLoginFilter autologinFilter /* (5)使用Filter實現URL級別的權限認證 (1)情景:在實際開發中我們經常把一些執行敏感操作的servlet映射到一些特殊目錄中,并用filter把這些特殊目錄保護起來,限制只能擁有相應訪問權限的用戶才能訪問這些目錄下的資源。從而在我們系統中實現一種URL級別的權限功能。 要求:為使Filter具有通用性,Filter保護的資源和相應的訪問權限通過filter參數的形式予以配置。 (2)系統中存在很多資源,將需要進行權限控制的資源,放入特殊路徑中,編寫過濾器管理訪問特殊路徑的請求,如果沒有相應身份和權限,控制無法訪問? 認證:who?are?you???用戶身份的識別?------------?登陸功能 權限:以認證為基礎?what?can?you?do???您能做什么??必須先登陸,才有身份,有了身份,才能確定可以執行哪些操作? package?com.itheima.filter; import?java.io.IOException; import?java.util.Enumeration; import?java.util.HashMap; import?java.util.Map; 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.HttpSession; import?com.itheima.domain.User; public?class?PrivilegeFilter?implements?Filter?{ private?FilterConfig?config?=?null; private?Map?map?=?new?HashMap(); public?void?destroy()?{ //?TODO?Auto-generated?method?stub } public?void?doFilter(ServletRequest?request,?ServletResponse?response, FilterChain?chain)?throws?IOException,?ServletException?{ //1.當前訪問的資源是否需要權限(當前訪問資源路徑是否是map中具有的需要權限控制的路徑的子路徑) HttpServletRequest?req?=?(HttpServletRequest)?request; String?uri?=?req.getRequestURI(); uri?=?uri.substring(config.getServletContext().getContextPath().length()); String?privilege?=?null; for(String?name?:?map.keySet()){ if(uri.startsWith(name)){ privilege?=?map.get(name); } } if(privilege?==?null){ //2.如果不需要權限,直接放行 chain.doFilter(request,?response); return; }else{//3.如果需要權限,判斷當前用戶具有的權限和訪問該資源需要的權限是否相匹配,如果匹配就放行,如果不匹配則提示 HttpSession??session?=?req.getSession(false); if(session?==?null?||?session.getAttribute("user")==null){ throw?new?RuntimeException("請先登錄"); } User?user?=?(User)?session.getAttribute("user"); if(user.getRole().equals(privilege)){ chain.doFilter(request,?response); return; }else{ throw?new?RuntimeException("沒有對應的權限!!!!"); } } } public?void?init(FilterConfig?filterConfig)?throws?ServletException?{ this.config?=?filterConfig; Enumeration?enumeration?=?config.getInitParameterNames(); while(enumeration.hasMoreElements()){ String?name?=?(String)?enumeration.nextElement(); String?value?=?config.getInitParameter(name); map.put(name,?value); } } } PrivilegeFilter com.itheima.filter.PrivilegeFilter param> /admin admin param> param> /user user param> PrivilegeFilter /* 11、MD5加密 /** ?*?使用md5的算法進行加密 ?*/ public?static?String?md5(String?plainText)?{ byte[]?secretBytes?=?null; try?{ secretBytes?=?MessageDigest.getInstance("md5").digest( plainText.getBytes()); }?catch?(NoSuchAlgorithmException?e)?{ throw?new?RuntimeException("沒有md5這個算法!"); } String?md5code?=?new?BigInteger(1,?secretBytes).toString(16); for?(int?i?=?0;?i? md5code?=?"0"?+?md5code; } return?md5code; } 如果將用戶密碼保存在cookie文件中,非常不安全的?,通常情況下密碼需要加密后才能保存到客戶端? *?使用md5算法對密碼進行加密? *?md5?加密算法是一個單向加密算法?,支持明文---密文?不支持密文解密? MySQL數據庫中提供md5?函數,可以完成md5?加密 mysql>?select?md5('123');? +----------------------------------+ |?md5('123')???????????????????????| +----------------------------------+ |?202cb962ac59075b964b07152d234b70?| +----------------------------------+ 解密后結果是32位數字?16進制表示? Java中提供類?MessageDigest?完成MD5加密 ------------------------------------------------------------------ 將數據表中所有密碼?變為密文?update?user?set?password?=?md5(password)?; 在Demo4Servlet?登陸邏輯中,對密碼進行md5?加密? 在AutoLoginFilter?因為從Cookie中獲得就是加密后密碼,所以登陸時無需再次加密? ------------------------------------------------------------------ MD5?在2004?年被王小云破解,md5算法是多對一加密算法,出現兩個加密后相同密文的明文很難發現?,王小云并沒有研究出md5?解密算法,研究出一種提高碰撞概率的算法? 12、Filter高級開發 (1)由于開發人員在filter中可以得到代表用戶請求和響應的request、response對象,因此在編程中可以使用Decorator(裝飾器)模式對request、response對象進行包裝,再把包裝對象傳給目標資源,從而實現一些特殊需求。 (2)Decorator設計模式的實現 1.首先看需要被增強對象繼承了什么接口或父類,編寫一個類也去繼承這些接口或父類。 2.在類中定義一個變量,變量類型即需增強對象的類型。 3.在類中定義一個構造函數,接收需增強的對象。 4.覆蓋需增強的方法,編寫增強的代碼。 (3)Decorator模式? 1、包裝類需要和被包裝對象?實現相同接口,或者繼承相同父類 2、包裝類需要持有?被包裝對象的引用? 在包裝類中定義成員變量,通過包裝類構造方法,傳入被包裝對象? 3、在包裝類中,可以控制原來那些方法需要加強 不需要加強?,調用被包裝對象的方法 需要加強,編寫增強代碼邏輯? ServletRequestWrapper?和?HttpServletRequestWrapper?提供對request對象進行包裝的方法,但是默認情況下每個方法都是調用原來request對象的方法,也就是說包裝類并沒有對request進行增強? 在這兩個包裝類基礎上,繼承HttpServletRequestWrapper?,覆蓋需要增強的方法即可? 13、request對象的增強 (1)Servlet?API?中提供了一個request對象的Decorator設計模式的默認實現類HttpServletRequestWrapper?,?(HttpServletRequestWrapper?類實現了request?接口中的所有方法,但這些方法的內部實現都是僅僅調用了一下所包裝的的?request?對象的對應方法)以避免用戶在對request對象進行增強時需要實現request接口中的所有方法。 (2)使用Decorator模式包裝request對象,完全解決get、post請求方式下的亂碼問題 14、response對象的增強 Servlet??API?中提供了response對象的Decorator設計模式的默認實現類HttpServletResponseWrapper?,?(HttpServletResponseWrapper類實現了response接口中的所有方法,但這些方法的內部實現都是僅僅調用了一下所包裝的的?response對象的對應方法)以避免用戶在對response對象進行增強時需要實現response接口中的所有方法。 15、response增強案例—壓縮響應 應用HttpServletResponseWrapper對象,壓縮響應正文內容。思路: 通過filter向目標頁面傳遞一個自定義的response對象。 在自定義的response對象中,重寫getOutputStream方法和getWriter方法,使目標資源調用此方法輸出頁面內容時,獲得的是我們自定義的ServletOutputStream對象。 在我們自定義的ServletOuputStream對象中,重寫write方法,使寫出的數據寫出到一個buffer中。 當頁面完成輸出后,在filter中就可得到頁面寫出的數據,從而我們可以調用GzipOuputStream對數據進行壓縮后再寫出給瀏覽器,以此完成響應正文件壓縮功能。 復習:Tomcat服務器內,提供對響應壓縮?配置實現? 在conf/server.xml?中? ???????????????connectionTimeout="20000"? ???????????????redirectPort="8443"/>?添加?compressableMimeType?和?compression 沒有壓縮?:??00:00:00.0000.0637553GET200text/htmlhttp://localhost/ ???????????????connectionTimeout="20000"? ???????????????redirectPort="8443"?compressableMimeType="text/html,text/xml,text/plain"?compression="on"/> 壓縮后?:??00:00:00.0000.1712715GET200text/htmlhttp://localhost/? Content-Encoding:?gzip Content-Length?:?2715 實際開發中,很多情況下,沒有權限配置server.xml??,無法通過tomcat配置開啟gzip?壓縮 編寫過濾器對響應數據進行gzip壓縮? flush?方法 只有沒有緩沖區字節流,FileOutputStream?不需要flush? 而字節數組ByteArrayOutputStream、字節包裝流、字符流?需要flush?-----?這些流在調用close方法時都會自動flush?
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看