初探 Servlet Filter
初探 Servlet Filter
Filter (過濾器)
先來看幾個最簡單的 Filter 吧!
// AllPatternFilter.java
@WebFilter("/*")
public class AllPatternFilter extends HttpFilter {
@Override
protected void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws IOException, ServletException {
System.out.println("任何 Servlet 請求都會經過我");
chain.doFilter(req, res); // 記得 FilterChain 的 doFilter() 方法要呼叫,才會往下走
}
}
// HelloWorldFilter.java
@WebFilter(
urlPatterns = {"/hello-world"}
)
public class HelloWorldFilter extends HttpFilter {
@Override
protected void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws IOException, ServletException {
System.out.println("/hello-world 的請求都會經過我");
chain.doFilter(req, res); // 記得 FilterChain 的 doFilter() 方法要呼叫,才會往下走
}
}
Filter 過濾器的使用其實跟 Servlet 很像, 粗淺瞭解它的話 一樣是繼承 一個類別、覆寫掉方法、定義 urlPattern ... 我也是這樣瞭解的,不過就是有些細節要注意就是
首先!基本的 @WebFilter() 的設定請幫我看 「Servlet 使用教戰守則 – Annotation 篇」 的 @WebFilter 片段
透過 @WebFilter() 我們可以定義我們 Filter 的 Filter 名稱、url 匹配規則 等等的... 很豐富,我們之後的文章會詳細介紹到 我們在最一開始只要會用 urlPatterns 就好了
可以看到第一個寫的是 /* 這就代表我們任何的請求都會經過 AllPatternFilter.java 這層 Filter
而第二個是 /hello-world 這也就是指定 /hello-world 這個 url 會經過 HelloWorldFilter.java 這層 Filter
而且實際上 /hello-world 是會經過 HelloWorldFilter.java 跟 AllPatternFilter.java 這兩層 Filter 的 順序是這樣的
// /hello-world 的請求都會經過我
// 任何 Servlet 請求都會經過我
如果要能夠客製化順序的話,目前我找到的解決方法只有使用 web.xml 來定義了! 可能匹配規則就不能完全用 Annotation 來寫了這樣
這一篇比較亂一點... 就先附上目錄結構吧!
├── src
│ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ └── judysocute
│ │ │ ├── AllPatternFilter.java
│ │ │ ├── HelloWorld.java
│ │ │ └── HelloWorldFilter.java
│ │ ├── resources
│ │ └── webapp
│ │ └── WEB-INF
│ │ └── web.xml
我們先把我們 Filter 的 Annotation 都拿掉
// AllPatternFilter.java
public class AllPatternFilter extends HttpFilter {
@Override
protected void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws IOException, ServletException {
System.out.println("任何 Servlet 請求都會經過我");
chain.doFilter(req, res); // 記得 FilterChain 的 doFilter() 方法要呼叫,才會往下走
}
}
// HelloWorldFilter.java
@WebFilter(
urlPatterns = {"/hello-world"}
)
public class HelloWorldFilter extends HttpFilter {
@Override
protected void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws IOException, ServletException {
System.out.println("/hello-world 的請求都會經過我");
chain.doFilter(req, res); // 記得 FilterChain 的 doFilter() 方法要呼叫,才會往下走
}
}
只留這樣,再來在 web.xml 定義內容
<!-- web.xml -->
<web-app version="4.0"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd">
<filter>
<filter-name>AllPattern</filter-name>
<filter-class>com.judysocute.AllPatternFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>AllPattern</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>HelloWorld</filter-name>
<filter-class>com.judysocute.HelloWorldFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HelloWorld</filter-name>
<url-pattern>/hello-world</url-pattern>
</filter-mapping>
</web-app>
Filter 的先後順序會依據 web.xml 內定義的順序