2-3-2 Java Web基礎-過濾器
阿新 • • 發佈:2020-09-12
過濾器 - Filter介紹
過濾器(Filter)是J2EE Servlet模組下的元件
Filter的作用是對URL進行統一的攔截處理
Filter常用於應用程式層面進行全域性處理
開發過濾器的三要素
任何過濾器都要實現javax.servlet.Filter介面
在Filter介面的doFilter()方法中編寫過濾器的功能程式碼
在web.xml中對過濾器進行配置,說明攔截的URL範圍
例項
1 import java.io.IOException; 2 3 import javax.servlet.Filter; 4 import javax.servlet.FilterChain;5 import javax.servlet.FilterConfig; 6 import javax.servlet.ServletException; 7 import javax.servlet.ServletRequest; 8 import javax.servlet.ServletResponse; 9 10 public class MyFirstFilter implements Filter { 11 12 @Override 13 public void destroy() { 14 // TODO Auto-generated method stub15 System.out.println("過濾器已被銷燬");; 16 } 17 18 @Override 19 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 20 throws IOException, ServletException { 21 // TODO Auto-generated method stub 22 System.out.println("過濾器已生效");23 chain.doFilter(request, response); 24 } 25 26 @Override 27 public void init(FilterConfig filterConfig) throws ServletException { 28 // TODO Auto-generated method stub 29 System.out.println("過濾器初始化成功"); 30 } 31 32 }
web.xml的配置
<?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>first-filter</display-name> <!-- filter標籤用於說明哪個類是過濾器,並在應用啟動時自動載入 --> <filter> <filter-name>MyFirstFilter</filter-name> <filter-class>com.mingm.filter.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> </web-app>
過濾器的生命週期
1.初始化 - Filter.init()
2.提供服務 - Filter.doFilter()
3.銷燬 - Filter.destory()
過濾器的特性
過濾器物件在Web應用啟動時被建立且全域性唯一
唯一的過濾器物件在併發環境中採用"多執行緒"提供服務
過濾器的兩種開發方式
過濾器的配置形式
在web.xml配置
<!-- filter標籤用於說明哪個類是過濾器,並在應用啟動時自動載入 --> <filter> <filter-name>MyFirstFilter</filter-name> <filter-class>com.imooc.filter.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>
過濾器的註解形式
1 import java.io.IOException; 2 3 import javax.servlet.Filter; 4 import javax.servlet.FilterChain; 5 import javax.servlet.FilterConfig; 6 import javax.servlet.ServletException; 7 import javax.servlet.ServletRequest; 8 import javax.servlet.ServletResponse; 9 import javax.servlet.annotation.WebFilter; 10 11 @WebFilter(filterName="MyAnnotationFilter",urlPatterns="/*") 12 public class MyAnnoationFilter implements Filter{ 13 14 @Override 15 public void destroy() { 16 // TODO Auto-generated method stub 17 18 } 19 20 @Override 21 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 22 throws IOException, ServletException { 23 System.out.println("註解形式過濾器已生效"); 24 // TODO Auto-generated method stub 25 chain.doFilter(request, response); 26 } 27 28 @Override 29 public void init(FilterConfig filterConfig) throws ServletException { 30 // TODO Auto-generated method stub 31 32 } 33 34 }
配置與註解如何選擇
配置維護性更好,適合全域性過濾
註解形式開發體驗更好,適合小型專案敏捷開發
開發字元過濾器解決Web中文亂碼問題
1 import java.io.IOException; 2 3 import javax.servlet.Filter; 4 import javax.servlet.FilterChain; 5 import javax.servlet.FilterConfig; 6 import javax.servlet.ServletException; 7 import javax.servlet.ServletRequest; 8 import javax.servlet.ServletResponse; 9 import javax.servlet.annotation.WebFilter; 10 import javax.servlet.annotation.WebInitParam; 11 import javax.servlet.http.HttpServletRequest; 12 import javax.servlet.http.HttpServletResponse; 13 @WebFilter(filterName="CharacterEncodingFilter",urlPatterns="/*", 14 initParams= { 15 @WebInitParam(name="encoding" , value="GBK"), 16 @WebInitParam(name="p1" , value="v1"), 17 @WebInitParam(name="p2" , value="v2") 18 }) 19 public class CharacterEncodingFilter implements Filter { 20 private String encoding; 21 @Override 22 public void init(FilterConfig filterConfig) throws ServletException { 23 // TODO Auto-generated method stub 24 encoding=filterConfig.getInitParameter("encoding"); 25 System.out.println("encoding:"+encoding); 26 } 27 28 @Override 29 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 30 throws IOException, ServletException { 31 // TODO Auto-generated method stub 32 HttpServletRequest req = (HttpServletRequest)request; 33 req.setCharacterEncoding(encoding); 34 HttpServletResponse res = (HttpServletResponse)response; 35 res.setContentType("text/html;charset=" + encoding); 36 chain.doFilter(request, response); 37 } 38 39 @Override 40 public void destroy() { 41 // TODO Auto-generated method stub 42 43 } 44 45 }
過濾引數化
上面程式碼是註解形式的過濾器引數化,配置在web.xml:
1 <filter> 2 <filter-name>CharacterEncodingFilter</filter-name> 3 <filter-class>com.mingm.filter.CharacterEncodingFilter</filter-class> 4 <init-param> 5 <param-name>encoding</param-name> 6 <param-value>UTF-8</param-value> 7 </init-param> 8 <init-param> 9 <param-name>p1</param-name> 10 <param-value>v1</param-value> 11 </init-param> 12 <init-param> 13 <param-name>p2</param-name> 14 <param-value>v2</param-value> 15 </init-param> 16 </filter> 17 <filter-mapping> 18 <filter-name>CharacterEncodingFilter</filter-name> 19 <url-pattern>/*</url-pattern> 20 </filter-mapping>
ServletRequest介面
ServletRequest是所有請求的頂層介面,代表任何請求
HttpServletRequest是Http協議請求的抽象介面,是J2EE標準
RequestFacade是HttpServletRequest介面的實現類,由Tomcat實現
url-pattern常用寫法
/index.jsp - 執行資源精確匹配
/servlet/* - 字首模糊匹配
*.jsp - 字尾模糊匹配
/與/*的區別
/指對映Web應用根路徑,且只對Servlet生效
預設首頁index.jsp會讓/失效
/與/*含義不同,前者指向根路徑.後者代表所有
過濾鏈開發注意事項
每一個過濾器應具有單獨功能
過濾器執行順序以<filter-mapping>為準
呼叫chain.doFilter()將請求向後傳遞
多端裝置自動匹配
1 import java.io.IOException; 2 3 import javax.servlet.Filter; 4 import javax.servlet.FilterChain; 5 import javax.servlet.FilterConfig; 6 import javax.servlet.ServletException; 7 import javax.servlet.ServletRequest; 8 import javax.servlet.ServletResponse; 9 import javax.servlet.http.HttpServletRequest; 10 import javax.servlet.http.HttpServletResponse; 11 12 public class DeviceAdapterFilter implements Filter{ 13 14 @Override 15 public void init(FilterConfig filterConfig) throws ServletException { 16 // TODO Auto-generated method stub 17 18 } 19 20 @Override 21 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 22 throws IOException, ServletException { 23 // TODO Auto-generated method stub 24 HttpServletRequest req = (HttpServletRequest)request; 25 HttpServletResponse res = (HttpServletResponse)response; 26 /* 27 /index.html 28 PC: /desktop/index.html 29 MOBILE: /mobile/index.html 30 /test.html 31 PC: /desktop/test.html 32 MOBILE: /mobile/test.html 33 */ 34 String uri = req.getRequestURI(); 35 System.out.println("URI:" + uri); 36 if(uri.startsWith("/desktop") || uri.startsWith("/mobile")) { 37 chain.doFilter(request, response); 38 }else { 39 String userAgent = req.getHeader("user-agent").toLowerCase(); 40 String targetURI=""; 41 if(userAgent.indexOf("android")!=-1 || userAgent.indexOf("iphone") != -1) { 42 targetURI = "/mobile" + uri; 43 System.out.println("移動端裝置正在訪問,重新跳轉URI:" + targetURI); 44 res.sendRedirect(targetURI); 45 }else { 46 targetURI = "/desktop" + uri; 47 System.out.println("PC端裝置正在訪問,重新跳轉URI:" + targetURI); 48 res.sendRedirect(targetURI); 49 } 50 } 51 } 52 53 @Override 54 public void destroy() { 55 // TODO Auto-generated method stub 56 57 } 58 59 }
web.xml
1 <filter> 2 <filter-name>DeviceAdapterFilter</filter-name> 3 <filter-class>com.mingm.filter.DeviceAdapterFilter</filter-class> 4 </filter> 5 <filter-mapping> 6 <filter-name>DeviceAdapterFilter</filter-name> 7 <url-pattern>*.html</url-pattern> 8 </filter-mapping>