【過濾器】web中過濾器的使用與亂碼問題解決

weixin_34259232發表於2017-08-25

一、過濾器Filter

1.filter的簡介

filter是對客戶端訪問資源的過濾,符合條件放行,不符合條件不放行,並且可以對目   標資源訪問前後進行邏輯處理

2.快速入門

步驟:

1)編寫一個過濾器的類實現Filter介面

2)實現介面中尚未實現的方法(著重實現doFilter方法)

3)在web.xml中進行配置(主要是配置要對哪些資源進行過濾)

(1)建立Filter實現Filter

攔截之後要放行。

package 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;
public class FirstFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // TODO Auto-generated method stub
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
//        自動攔截請求
            System.out.println("filter running.......");
//            放行
            chain.doFilter(request, response);
    }

    @Override
    public void destroy() {
        // TODO Auto-generated method stub

    }

}

 

(2)Web.xml配置一下

<filter>
      <filter-name>FirstFilter</filter-name>
      <filter-class>filter.FirstFilter</filter-class>
  </filter>
  <filter-mapping>
      <filter-name>FirstFilter</filter-name>
      <url-pattern>/*</url-pattern>
  </filter-mapping>

 

/*代表所有請求,如果不放行,客戶端得不到響應。

3.Filter的API詳解

(1)filter生命週期及其與生命週期相關的方法

Filter介面有三個方法,並且這個三個都是與Filter的生命相關的方法

init(Filterconfig):代表filter物件初始化方法 filter物件建立時執行

doFilter(ServletRequest,ServletResponse,FilterCha):代表filter執行過濾的核心方法,如果某資源在已經被配置到這個filter進行過濾的話,那麼每次訪問這個資源都會執行doFilter方法

destory():代表是filter銷燬方法 當filter物件銷燬時執行該方法

 

Filter物件的生命週期:

Filter何時建立:伺服器啟動時就建立該filter物件

中間在客戶端訪問過濾器過濾的資源時呼叫doFilter方法

Filter何時銷燬:伺服器關閉時filter銷燬

 

(2)Filter的API詳解

1)init(FilterConfig)

其中引數config代表 該Filter物件的配置資訊的物件,內部封裝是該filter的配置資訊。

 

2)destory()方法

filter物件銷燬時執行

3)doFilter方法

doFilter(ServletRequest,ServletResponse,FilterChain)

其中的引數:

ServletRequest/ServletResponse:每次在執行doFilter方法時 web容器負責建立一個request和一個response物件作為doFilter的引數傳遞進來。該request個該response就是在訪問目標資源的service方法時的request和response。

FilterChain:過濾器鏈物件,通過該物件的doFilter方法可以放行該請求

 

4.Filter的配置

<filter>
      <filter-name>Filter2</filter-name>
      <filter-class>filter.Filter2</filter-class>
       <init-param>
          <param-name>name</param-name>
          <param-value>dahua</param-value>
      </init-param>
  </filter>
  <filter-mapping>
      <filter-name>Filter2</filter-name>
      <url-pattern>/*</url-pattern>
      <dispatcher>REQUEST</dispatcher>
  </filter-mapping>

 

也可以直接攔截Servlet(等價於url-pattern   /sertvle1)

<filter-mapping>
      <filter-name>Filter2</filter-name>
      <servlet-name>servlet</servlet-name>
  </filter-mapping>

①url-pattern配置時(不用寫工程名字,直接寫路徑)

1)完全匹配  /sertvle1

2)目錄匹配  /aaa/bbb/* ----最多的

/user/*:訪問前臺的資源進入此過濾器

/admin/*:訪問後臺的資源時執行此過濾器

3)副檔名匹配  *.abc  *.jsp

 

注意:url-pattern可以使用servlet-name替代,也可以混用

 

dispatcher:訪問的方式(瞭解)

REQUEST:預設值,代表直接訪問某個資源時執行filter

        轉發攔截一次,重定向2次

FORWARD:轉發時才執行filter

INCLUDE: 包含資源時執行filter

ERROR:發生錯誤時 進行跳轉是執行filter

 

5.總結Filter的作用?

1)公共程式碼的提取

2)可以對request和response中的方法進行增強(裝飾者模式/動態代理)

3)進行許可權控制

6.總結

1.Filter先寫實現方法,再在web.xml中配置(名字,對映以及攔截的請求)

url-pattern配置時  不寫工程名字

1)完全匹配  /sertvle1

2)目錄匹配  /aaa/bbb/* ----最多的

/user/*:訪問前臺的資源進入此過濾器

/admin/*:訪問後臺的資源時執行此過濾器

3)副檔名匹配  *.abc  *.jsp

2.過濾器的執行順序根據你在web.xml中對映的順序執行。

3.可以過濾使用者請求:

package 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;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import daomain.User;

public class RequestFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // TODO Auto-generated method stub
        
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        // TODO Auto-generated method stub
        HttpServletRequest req =(HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;
        HttpSession session = req.getSession();
        User user = (User) session.getAttribute("user");
        if(user==null){
            request.getRequestDispatcher("/index.jsp").forward(request, response);
        }
        else{
            System.out.println(user);
        }
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {
        // TODO Auto-generated method stub
        
    }

    
}

 

二、設定編碼格式

1.post提交

(1)編寫過濾器程式碼

@Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        request.setCharacterEncoding("utf-8");
        chain.doFilter(request, response);
    }

(2)Web.xml中隊所有請求攔截

(3)後臺直接接受post提交的中文資料

2.get提交

接收前端:

String para = request.getParameter("name");
String para2 = new String(para.getBytes("iso-8859-1"),"utf-8");

 

向前端傳送

//設定response查詢的碼錶 
        //response.setCharacterEncoding("UTF-8");
        
        //通過一個頭 Content-Type 告知客戶端使用何種碼錶
        //response.setHeader("Content-Type", "text/html;charset=UTF-8");
        
//        這句與上句等價,開發中只用寫這句,tomcat自動設定第一句
        response.setContentType("text/html;charset=UTF-8");

 

三、裝飾者模式解決亂碼

package filter;


import java.io.IOException;
import java.io.UnsupportedEncodingException;

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{

    
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        
        //request.setCharacterEncoding("UTF-8");
        
        //在傳遞request之前對request的getParameter方法進行增強
        /*
         * 裝飾者模式(包裝)
         * 
         * 1、增強類與被增強的類要實現統一介面
         * 2、在增強類中傳入被增強的類
         * 3、需要增強的方法重寫 不需要增強的方法呼叫被增強物件的
         * 
         */
        
        //被增強的物件
        HttpServletRequest req = (HttpServletRequest) request;
        //增強物件
        EnhanceRequest enhanceRequest = new EnhanceRequest(req);
        
        
        chain.doFilter(enhanceRequest, response);
        
    }

    @Override
    public void destroy() {
        
    }
    
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        
    }

}

class EnhanceRequest extends HttpServletRequestWrapper{
    
    private HttpServletRequest request;

    public EnhanceRequest(HttpServletRequest request) {
        super(request);
        this.request = request;
    }
    
    //對getParaameter增強
    @Override
    public String getParameter(String name) {
        String parameter = request.getParameter(name);//亂碼
        try {
            parameter = new String(parameter.getBytes("iso8859-1"),"UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return parameter;
    }
    
}

 四、過濾登入的過濾器

 <filter>
  <filter-name>sessionFilter</filter-name>
  <filter-class>com.FlyPig.util.filter_session</filter-class>
 </filter>

 <filter-mapping>
  <filter-name>sessionFilter</filter-name>
  <url-pattern>/*</url-pattern>
 </filter-mapping>

 

filter程式碼如下:起到了過濾登陸介面login.jsp和根路徑以外的過濾

 1 package com.FlyPig.util;
 2 
 3 import java.io.IOException;
 4 
 5 import javax.servlet.Filter;
 6 import javax.servlet.FilterChain;
 7 import javax.servlet.FilterConfig;
 8 import javax.servlet.ServletException;
 9 import javax.servlet.ServletRequest;
10 import javax.servlet.ServletResponse;
11 import javax.servlet.http.HttpServletRequest;
12 import javax.servlet.http.HttpServletResponse;
13 import javax.servlet.http.HttpSession;
14 
15 public class filter_session implements Filter {
16     private String encoding;
17 
18     public filter_session() {
19     }
20 
21     public void init(FilterConfig filterconfig) throws ServletException {
22         encoding = "utf-8";
23     }
24 
25     public void doFilter(ServletRequest servletrequest,
26             ServletResponse servletresponse, FilterChain filterchain)
27             throws IOException, ServletException {
28         servletrequest.setCharacterEncoding(encoding);
29         servletresponse.setCharacterEncoding(encoding);
30         HttpServletRequest req=(HttpServletRequest)servletrequest;
31         HttpSession session=req.getSession();
32         HttpServletResponse resp=(HttpServletResponse) servletresponse;
33         
34         String url=req.getRequestURI();
35         System.out.println(url);
36         if(!url.equals("/FlyPig")&&!url.equals("/FlyPig/login.jsp")){
37             if(session.getAttribute("username")==null||session.getAttribute("username")==""){
38                 resp.sendRedirect("login.jsp");
39                 return ;
40             }
41         }
42         
43         
44         filterchain.doFilter(servletrequest, servletresponse);
45     }
46 
47     public void destroy() {
48     }
49 }

 

補充:過濾器在請求前可以執行一次,請求後也可以執行:

//前處理

filterchain.doFilter(servletrequest, servletresponse);

//後處理

 

  也就是說在請求完成並且頁面載入完成之後會執行後處理,從Java的語法來看放行之後方法沒有retur,所以方法會繼續執行。用於在處理所有請求的一次請求前和請求後處理。

 

相關文章