1. 程式人生 > 其它 >Spring-編碼過濾----解析Filter實現原理,Java中高階面試題最新

Spring-編碼過濾----解析Filter實現原理,Java中高階面試題最新

forceEncoding true
<filter-mapping>
    <filter-name>EncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

### 二、過濾器(Filter)的概念

1.  過濾器位於客戶端和web應用程式之間,用於檢查和修改兩者之間流過的請求和響應。

2.  在請求到達Servlet/JSP之前,過濾器截獲請求。

3.  在響應送給客戶端之前,過濾器截獲響應。

4.  多個過濾器形成一個過濾器鏈,過濾器鏈中不同過濾器的先後順序由部署檔案web.xml中過濾器對映的順序決定。

5.  最先截獲客戶端請求的過濾器將最後截獲Servlet/JSP的響應資訊。

### 三、實現過濾器

可以通過實現javax.servlet.Filter類來實現自定義過濾器。

public class MyFilter implements Filter {

public void init(FilterConfig fc) { //過濾器初始化程式碼 }

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
    try { //在這裡可以對客戶端請求進行檢查  //沿過濾器鏈將請求傳遞到下一個過濾器。 chain.doFilter(request, response); //在這裡可以對響應進行處理 } catch (IOException e) {
        e.printStackTrace();
    } catch (ServletException e) {
        e.printStackTrace();
    }
}

public void destroy( ) { //過濾器被銷燬時執行的程式碼 }

}


### 四、過濾器的鏈式結構

可以為一個Web應用元件部署多個過濾器,這些過濾器組成一個過濾器鏈,每個過濾器只執行某個特定的操作或者檢查。這樣請求在到達被訪問的目標之前,需要經過這個過濾器鏈。
![image.png](https://upload-images.jianshu.io/upload_images/24613101-49be8bf58eae19b4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


### 五、如何實現鏈式結構

其實Filter的鏈式結構是使用了Java中的責任鏈模式。下面我用簡單的例子來實現責任鏈模式,然後再來講解Spring容器中的實現。下面是我整個的包結構:

![image.png](https://upload-images.jianshu.io/upload_images/24613101-fd74aec051273305.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

然後我再來詳細說明每個類的說明: 1、Filter.java。用來模擬Servlet中的Filter.java.

public interface Filter {

void doFilter(Request request, Response response, FilterChain filterChain);

}


2、Request.java。用來模擬Servlet中HttpServletRequest.java。

@Data
public class Request {

private String requestStr;

}


3、Response.java。用來模擬Servlet中的HttpServletResponse.java。

@Data
public class Response {

private String responseStr = "responseStr";

}


4、HtmlFilter.java。用來把”:)”轉換成”^-^”,並且標記執行順序

public class HtmlFilter implements Filter {

@Override
public void doFilter(Request request, Response response, FilterChain filterChain) {
    String newRequestStr = request.getRequestStr().replace(":)", "^-^") + "----HtmlFilter";
    request.setRequestStr(newRequestStr);
    filterChain.doFilter(request, response, filterChain);
    String newResponseStr = response.getResponseStr() + "----HtmlFilter";
    response.setResponseStr(newResponseStr);
}

}


5、TextFilter.java。用來做字串轉換

public class TextFilter implements Filter {
@Override
public void doFilter(Request request, Response response, FilterChain filterChain) {
String newRequestStr = request.getRequestStr().replace("中國10.1", "中國") + "----TextFilter";
request.setRequestStr(newRequestStr);
filterChain.doFilter(request, response, filterChain);
String newResponseStr = response.getResponseStr() + "----TextFilter";
response.setResponseStr(newResponseStr);
}
}


6、FilterChain.java。用來模擬Servlet中的FilterChain,只不過這個類是一個介面。這個類同時也是實現了Filter這個介面,這樣設計更加精巧。等下我們對比一下Spring中的對ServletChain的實現就可以發現了。

public class FilterChain implements Filter {

private List<Filter> filters = Lists.newArrayList();

private int currentPosition = 0;

public FilterChain addFilter(Filter filter){
    this.filters.add(filter);
    return this;
}

@Override
public void doFilter(Request request, Response response, FilterChain filterChain) {

    if (this.currentPosition == this.filters.size()) {
        return;
    }
    this.currentPosition++;
    Filter nextFilter = this.filters.get(this.currentPosition - 1);
    nextFilter.doFilter(request, response, this);
}

}


7、Client.java。用來測試結果。

public class Client {

public static void main(String[] args) {
    String requestStr = "1111111,2222222:),中國10.1國慶節....";
    Request request = new Request();
    request.setRequestStr(requestStr);
    Response response = new Response();
    FilterChain filterChain = new FilterChain();
    filterChain.addFilter(new HtmlFilter()).addFilter(new TextFilter());
    filterChain.doFilter(request, response, filterChain);
    System.out.println(request.getRequestStr());
    System.out.println(response.getResponseStr());
}

}


我們先來看看執行結果,再來分析實現原理。執行結果如下:



# 總結

螞蟻面試比較重視基礎,所以Java那些基本功一定要紮實。螞蟻的工作環境還是挺讚的,因為我面的是穩定性保障部門,還有許多單獨的小組,什麼三年1班,很有青春的感覺。面試官基本水平都比較高,基本都P7以上,除了基礎還問了不少架構設計方面的問題,收穫還是挺大的。

**[CodeChina開源專案:【一線大廠Java面試題解析+核心總結學習筆記+最新講解視訊】](https://ali1024.coding.net/public/P7/Java/git)**

* * *

**經歷這次面試我還通過一些渠道發現了需要大廠真實面試主要有**:螞蟻金服、拼多多、阿里雲、百度、唯品會、攜程、豐巢科技、樂信、軟通動力、OPPO、銀盛支付、中國平安等初,中級,高階Java面試題集合,附帶超詳細答案,希望能幫助到大家。

![螞蟻金服5面,總結了49個面試題,遇到的面試官都是P7級別以上](https://upload-images.jianshu.io/upload_images/24616006-2b976d3b5a750638?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)