1. 程式人生 > 實用技巧 >2-3-2 Java Web基礎-過濾器

2-3-2 Java Web基礎-過濾器

過濾器 - 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 stub
15 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>