有沒有發現我們前幾週的專案進度有個大 Bug!就是我們的程式中,幾乎沒有任何的例外判斷…
為什麼呢?
就是因為我們這週的標題
Filter
我打算把 Servlet 所有的例外處理都交給 Filter 來過濾,不過這週先不會直接把 Filter 用進專案,我們還是要先教會大家什麼是 Fliter 吧!
開始吧!!
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 內定義的順序
畢竟只是初探,下一篇會更仔細介紹的!