# JavaServlet - 07 - Filter 過濾器
> ### Filer簡介
擔任瀏覽器與Servlet/JSP之間的一個中介處理者,
request 的前置處理 和 response 的後置處理,皆可交由 Filter 來完成。
> ### Filter 五種用途:
1. Authentication filters 權限
2. Logging and auditing filters 記錄檔
3. Image conversion filters 圖檔的轉換
4. Data compression filter 後置
5. Encryption filters 轉換編碼
---
> ### Filter 製作範例:
1. 建立 2個 新的 Filter 類別,分別命名為「MyFilter1」、「MyFilter2」,並將 @WebFilter 名稱改成 「FilterDemo」
2. 建立 1個 新的 Servlet 類別,命名為「"/FilterDemo"」
> 說明:
1. FilterChain 物件是透過 doFilter() 來呼叫下一個 Filter,並將 request response 物件傳給下一個 Filter 。
- chain.doFilter(request, response)
- 會一直呼叫下一個Filter直到無下一個Fitler為止。
- 若無下一個Filter,則會呼叫原本請求的網頁。
2. 前置後置分辨:
- 寫在 chain.doFilter(request,response) 之前就是 「前置,
- 寫在 chain.doFilter(request,response) 之後就是 「後置」。
MyFilter1.java:
```java=
@WebFilter("/FilterDemo") //webfilter 要改成 servlet name
public class MyFilter1 implements Filter {
public void destroy() {}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
PrintWriter out = response.getWriter();
out.write("Pre-processing of MyFilter1<br>"); // 前置:做之前要做什麼事
//有兩個前置 先做1前置在做2前置
chain.doFilter(request, response); // 會詢問是否還有下一個doFilter
out.write("Post-processing of MyFilter1<br>"); // 後置:做完之後要做什麼事
}
public void init(FilterConfig fConfig)
throws ServletException {}
}
```
MyFilter2.java:
```java=
@WebFilter("/FilterDemo") //webfilter 要改成 servlet name
public class MyFilter1 implements Filter {
public void destroy() {}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
PrintWriter out = response.getWriter();
out.write("Pre-processing of MyFilter2<br>"); // 前置:做之前要做什麼事
//有兩個前置 先做1前置在做2前置
chain.doFilter(request, response); // 不可以刪除
out.write("Post-processing of MyFilter2<br>"); // 後置:做完之後要做什麼事
}
public void init(FilterConfig fConfig)
throws ServletException {}
}
```
FilterDemo.java : -> Run Server
``` java=
@WebServlet("/FilterDemo")
public class FilterDemo extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
PrintWriter out = response.getWriter();
for(int i=0;i<3;i++) {
out.write("Filter Demo!!<br>");
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
```
ans: 先開始的後結束,後開始的先結束。
```html
Pre-processing of MyFilter1
Pre-processing of MyFilter2
Filter Demo!!
Filter Demo!!
Filter Demo!!
Post-processing of MyFilter2
Post-processing of MyFilter1
```
---
> ### Filter初始參數值設定:
1. 使用 @WebFilter 的 InitParams 屬性設定 Filter 初始參數值
- initParams(WebInitParam[]): 可設定多個初始參數值。
2. @WebInitParam: 用來設定Fitler初始參數值,有兩個屬性。
- name(String) : 設定初始參數值的名稱。
- value(String) : 設定初始參數值。
初始參數值設定範例:
``` java
@WebFilter(urlPatterns="/EncodingFilterDemo",
initParams= {@WebInitParam(name="encoding",value="UTF-8"),
@WebInitParam(name="aaa",value="123")})
```
---
> ### FilterConfig 介面
1. FilterConfig 介面方法:
```java=
String getFilterName() // 取得Filter名字
String getInitParameter(String name) // 抓取Init值
Enumeration getInitParameterNames() // 抓取參數名稱
```
2. 在 init(FitlerConfig) 中取得 Filter 的初始參數值:
```java=
public void init(FilterConfig config)
throws ServletException {
encoding = config.getInitParamer("encoding")
}
```
3. 利用 Filter 的初始參數值來「解決中文亂碼的問題」,無需再每個servlet解決中文問題。
EncodingFilterDemo.java
```java=
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.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
@WebFilter(urlPatterns="/EncodingFilterDemo",
initParams= {@WebInitParam(name="encoding", value="UTF-8")})
public class EncodingFilter implements Filter {
String encoding = null;
public void destroy(){}
public void init(FilterConfig fConfig)
throws ServletException {
// 抓取 Init 值
encoding = fConfig.getInitParameter("encoding");
}
// 當別人給 .class 無法更改源碼(.java)時的解決方法,透過filter方式解決
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
//chain.doFilter(request, response);
if(encoding!=null) {
request.setCharacterEncoding(encoding);
response.setContentType("text/html;charset="+encoding);
}
chain.doFilter(request, response);
}
}
```
---
> ### End
``` java
```
---
###### tags: `JavaServlet`
{"metaMigratedAt":"2023-06-15T18:16:32.890Z","metaMigratedFrom":"Content","title":"JavaServlet - 07 - Filter 過濾器","breaks":true,"contributors":"[{\"id\":\"a0c29f22-c0c5-445f-9bdd-ffcabd39d816\",\"add\":6063,\"del\":982}]"}