<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>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                # 過濾器 [TOC] ## 導學 過濾器-Filter,其實可以見名知意,就像我們日常生活中的凈化器,過濾網一樣,用于在訪問資源文件之前,通過一系列的過濾器對請求進行修改、判斷等,把不符合規則的請求在中途攔截或修改。也可以對響應進行過濾,攔截或修改響應。 ## 過濾器初識 * Filter過濾器 (Filter)是J2EE Servlet模塊下的組件 * Filter的作用是對URL進行統一的攔截處理 * Filter通常用于應用程序層面進行全局處理 ![](https://img.kancloud.cn/d6/da/d6da684803492d66300c9ffe58c1734f_876x421.png) **開發過濾器的三要素** 1. 任何過濾器都要實現javax.servlet.Filtere接口 2. 在filter接口的doFilter()方法中編寫過濾器的功能代碼(一個過濾器一個功能) 3. 在web.xml中對過濾器進行配置,說明攔截URL的范圍 ~~~ public class MyFirstFilter implements Filter{ //銷毀 @Override public void destroy() { } /** * * @param request * @param response * @param chain 過濾鏈對象 * @throws IOException * @throws ServletException */ @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("過濾器已生效!"); //將請求與響應對象沿著過濾鏈依次向后傳遞,如果不調用該方法,請求無法正常的向后被處理 chain.doFilter(request, response); } //初始化方法 @Override public void init(FilterConfig arg0) throws ServletException { } } ~~~ ~~~ <!-- 配置過濾器,filter標簽用于說明哪個類是過濾器,并在應用啟動的時候自動加載 --> <filter> <filter-name>myFirstFilter</filter-name> <filter-class>com.dodoke.firstfilter.MyFirstFilter</filter-class> </filter> <!-- filter-mapping標簽用于說明過濾器對URL應用的范圍,要點有二: 1、filter-name 過濾器名稱與filter.filter-name保持一致 2、url-pattern 說明過濾器作用范圍,/*代表對所有URL進行過濾 --> <filter-mapping> <filter-name>myFirstFilter</filter-name> <!-- 指明過濾器能夠過濾的請求映射范圍 --> <url-pattern>/*</url-pattern> </filter-mapping> ~~~ ~~~ @WebServlet("/hello") public class HelloServlet extends HttpServlet { private static final long serialVersionUID = 1L; public HelloServlet() { super(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); response.getWriter().println("Hello,world!!!"); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } } ~~~ ~~~ <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <h1>我是默認首頁</h1> </body> </html> ~~~ 無論是請求servlet還是請求靜態資源的時候,只要過濾器范文允許,都會實現過濾任務。 ## 過濾器的生命周期 ![](https://img.kancloud.cn/2d/19/2d195948b56e18df7a81e1ef082c7b05_289x348.png) 先進行web.xml配置文件的加載,然后進行初始化工作,調用`Filter.init()`對當前過濾器進行初始化,執行時機tomcat啟動后會自動創建Filter這個過濾器對象,一旦對象創建完,馬上執行`Filter.init()`方法。提供服務Filter.doilter(),銷毀- Filter.destroy()執行時機應用關閉或者重啟時。 ~~~ public class MyFirstFilter implements Filter { @Override public void destroy() { System.out.println("過濾器已被銷毀");; } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("過濾器已生效"); chain.doFilter(request, response); } @Override public void init(FilterConfig filterConfig) throws ServletException { System.out.println("過濾器初始化成功"); } } ~~~ **過濾器的特性:** * 過濾器對象在Web應用啟動時被創建且全局唯一 * 唯一的過濾器對象在并發環境中采用“多線程”提供服務(單例多線程方式) 雖然全局只有一個過濾器對象,但是如果是在并發環節中,每一個請求進來的時候,過濾器都會為其創建一個獨立的線程來提供服務,線程和線程之間他們是彼此不受影響的,正是因為叫單例多線程的這么一種設計,既保證了過濾器不會因為頻繁創建對象消耗系統資源,同時又采用多線程方式,有效提高了多用戶在訪問同一個過濾器時的執行速度 ## 過濾器的兩種開發方式 在之前開發過濾器的時候,我們使用配置文件中注冊的形式完成了過濾器的開發。其實類似于servlet,過濾器的配置同樣可以使用注解完成。 ~~~ 過濾器注解形式 @WebFilter(filterName="",urlPatterns="") ~~~ **過濾器兩種開發方式** * 配置形式維護性更好,適用應用全局過濾 xml中配置 * 注解形式開發體驗更好,適用于小型項目敏捷開發 ~~~ //filterName 指明過濾器名稱,不同的過濾器需要保證過濾器名稱不同,否則過濾器失效。 urlPatterns指明過濾哪些URL @WebFilter(filterName="MyAnnotationFilter",urlPatterns="/*") public class MyAnnoationFilter implements Filter{ @Override public void destroy() { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("注解形式過濾器已生效"); chain.doFilter(request, response); } @Override public void init(FilterConfig filterConfig) throws ServletException { } } ~~~ **Tomcat是如何發現過濾器并啟動過濾器的?** Servlet3.0版本之后,默認對注解有了支持。每次應用程序啟動時,Tomcat會對項目內的所有class字節碼文件(java編譯后的文件)進行掃描,當掃描到WebFlter注解時,則啟用這個過濾器。 同時存在配置形式和注解形式的過濾器時,會先執行配置形式過濾器。一般來說,整個項目只需要采用一種形式的過濾器,盡可能避免使用兩種形式。 ## 案例:開發字符集過濾器 主要任務,解決開發過程中的中文亂碼問題。 ![](https://img.kancloud.cn/a8/f2/a8f26e78b5fc7d499b2bb416517fc9f0_869x448.png) 在進行開發的時候,如果存在中文,在每一個有中文內容的servlet中都需要進行字符編碼的設置,這對我們來說是重復的工作,所以我們可以借助過濾器實現對每個請求與響應的編碼設置。 ~~~ @WebFilter(filterName="CharacterEncodingFilter",urlPatterns="/*") public class CharacterEncodingFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //注意此處不是我們之前使用的HttpServletRequest和HttpServletResponse HttpServletRequest req = (HttpServletRequest)request; req.setCharacterEncoding("UTF-8"); HttpServletResponse res = (HttpServletResponse)response; res.setContentType("text/html;charset=UTF-8"); chain.doFilter(request, response); } @Override public void destroy() { } } ~~~ 或采用 ~~~ xml配置: <filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class>com.dodoke.filter.CharacterEncodingFilter</filter-class> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> ~~~ ![](https://img.kancloud.cn/82/aa/82aa7ea21ff8eea33580a13fab10896c_576x349.png) **為什么doFilter使用的是ServletRequest而不是HttpServletRequest?** 過濾器過濾的不是只有web頁面的請求和響應,同時也需要過濾其他類型的請求和響應,其中涉及J2EE的底層機制。 ServletRequest接口是所有類型請求的最頂層的接口,包含了所有請求接口的通用方法。HttpServletRequest接口是其中的一個子接口,擴展定義自己的方法,是針對Http協議進行定義。 RequestFacade類是tomcat服務器針對HttpServletRequest接口的實現類,如果使用別的web服務器,實現類也就不是RequestFacade了。 J2EE是定制者,定制所有的接口,而實現類都是由三方廠商自己定制,此處servlet-api.jar就是J2EE的規范,catalina.jar是由Tomcat提供的實現類。響應接口同理。 ## 過濾器開發技巧 **過濾器參數化** * 過濾器為了增強靈活性,允許配置信息放在web.xml * 在web.xml中配置<init-param>設置過濾器參數 ~~~ <filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class>com.dodoke.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>GBK</param-value> </init-param> <init-param> <param-name>p1</param-name> <param-value>v1</param-value> </init-param> <init-param> <param-name>p2</param-name> <param-value>v2</param-value> </init-param> </filter> ~~~ ~~~ @WebFilter(filterName="CharacterEncodingFilter",urlPatterns="/*", initParams= { @WebInitParam(name="encoding" , value="GBK"), @WebInitParam(name="p1" , value="v1"), @WebInitParam(name="p2" , value="v2") }) public class CharacterEncodingFilter implements Filter { private String encoding; @Override public void init(FilterConfig filterConfig) throws ServletException { encoding=filterConfig.getInitParameter("encoding"); System.out.println("encoding:"+encoding); } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //注意此處不是我們之前使用的HttpServletRequest和HttpServletResponse HttpServletRequest req = (HttpServletRequest)request; req.setCharacterEncoding("UTF-8"); HttpServletResponse res = (HttpServletResponse)response; res.setContentType("text/html;charset=UTF-8"); chain.doFilter(request, response); } @Override public void destroy() { } } ~~~ ## url-pattern設置過濾范圍 **url-pattern常用寫法:** * `/index.jsp` - 執行資源精準匹配 * `/servlet/*`-以前綴進行模糊匹配(匹配以url中以servlet開頭的) * `*.jsp`-以后綴進行模糊匹配 url-pattern允許組合使用形成組合鏈。 ~~~ <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> I'm index page! </body> </html> ~~~ ~~~ <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> I'm test page! </body> </html> ~~~ ~~~ @WebServlet("/servlet/sample1") public class SampleServlet1 extends HttpServlet { private static final long serialVersionUID = 1L; public SampleServlet1() { super(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.getWriter().println("I'm " + this.getClass().getSimpleName()); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } } ~~~ ~~~ @WebServlet("/") public class SampleServlet2 extends HttpServlet { private static final long serialVersionUID = 1L; public SampleServlet2() { super(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.getWriter().println("I'm " + this.getClass().getSimpleName()); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } } ~~~ ~~~ /*@WebFilter(filterName="UrlPatternFilter" , urlPatterns= { "/","/servlet/*","*.jsp" })*/ //復雜url,還是使用配置比較好 public class UrlPatternFilter implements Filter{ @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest)request; HttpServletResponse res = (HttpServletResponse)response; System.out.println("攔截到:" + req.getRequestURL()); chain.doFilter(request, response); } @Override public void destroy() { } } ~~~ ~~~ <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1"> <display-name>url-pattern</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <filter> <filter-name>UrlPatternFilter</filter-name> <filter-class>com.imooc.filter.UrlPatternFilter</filter-class> </filter> <filter-mapping> <filter-name>UrlPatternFilter</filter-name> <url-pattern>/</url-pattern> </filter-mapping> <filter-mapping> <filter-name>UrlPatternFilter</filter-name> <url-pattern>/servlet/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>UrlPatternFilter</filter-name> <url-pattern>*.jsp</url-pattern> </filter-mapping> </web-app> ~~~ **映射的問題:** * /指映射Web應用根路徑,且只對Servlet生效 * 默認首頁index.jsp會讓/失效 * /與/*含義不同,前者指向根路徑,后者代表所有 ## 過濾鏈 **過濾鏈開發注意事項:** * 每一個過濾器應具有單獨職能 * 調用chain.doFiiter()將請求向后傳遞 * 過濾鏈是雙向的,響應返回時按逆序通過過濾鏈 * 過濾器的執行順序以XML配置中的<filter-mapping>從上到下執行 * 以注解形式設置過濾器時,過濾器執行順序按過濾器類名(不是注解中的filterName)的大小順序進行,如:filterA filterZ filterV三個過濾器執行順序為AVZ(不合理)類名有獨特含義,不能特地為了過濾鏈的執行順序而修改過濾器類名 ## 案例:多端設備自動匹配 ~~~ <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <h1>這是客戶端頁面</h1> </body> </html> ~~~ ~~~ <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <h1>這是移動端頁面</h1> </body> </html> ~~~ ~~~ public class DeviceAdapterFilter implements Filter{ @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest)request; HttpServletResponse res = (HttpServletResponse)response; /*原理:將不同端的頁面放置在不同的文件夾中,判斷請求的路徑,增加前綴 /index.html PC: /desktop/index.html MOBILE: /mobile/index.html /test.html PC: /desktop/test.html MOBILE: /mobile/test.html */ //注意區分url和uri String uri = req.getRequestURI(); System.out.println("URI:" + uri); if(uri.startsWith("/desktop") || uri.startsWith("/mobile")) { chain.doFilter(request, response); }else { //獲取請求主體,并全部轉為小寫 String userAgent = req.getHeader("user-agent").toLowerCase(); String targetURI=""; if(userAgent.indexOf("android")!=-1 || userAgent.indexOf("iphone") != -1) { targetURI = "/mobile" + uri; System.out.println("移動端設備正在訪問,重新跳轉URI:" + targetURI); //此處將原始URI修改成targetURI后,不進入過濾鏈。 //而是利用響應重定向senRedirect(targetURI)使瀏覽器重新發送請求,此時請求便能通過過濾器。 res.sendRedirect(targetURI); }else { targetURI = "/desktop" + uri; System.out.println("PC端設備正在訪問,重新跳轉URI:" + targetURI); res.sendRedirect(targetURI); } } } @Override public void destroy() { } } ~~~ ~~~ <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1"> <display-name>device-adapter</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <filter> <filter-name>DeviceAdapterFilter</filter-name> <filter-class>com.dodoke.filter.DeviceAdapterFilter</filter-class> </filter> <filter-mapping> <filter-name>DeviceAdapterFilter</filter-name> <url-pattern>*.html</url-pattern> </filter-mapping> </web-app> ~~~
                  <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>

                              哎呀哎呀视频在线观看