第10章 フィルタ
フィルタ
homepage
# **フィルタ** *** 「フィルタ」とはクライアントからのリクエストおよびレスポンスに対して、リソース(サーブレット/JSP/HTMLなど)での処理の前および後に何らかの処理を行うオブジェクトの事です。リクエストのパラメータ値を変更したり、ログの出力を行ったり様々なものが考えられます。<br> フィルタの機構が追加されたのは、サーブレット2.3からです。それまでにもフィルタの機構はベンダー独自に組み込まれていたのですが、バージョン2.3からはサーブレット標準の機能となりました。これによりベンダーに依存しないフィルタ機構を実現する事ができます。<br> <br> ``` サーブレットAを呼び出す フィルタAが実行される サーブレットAが実行される ``` また多段にフィルターをかけることも可能です。 ``` サーブレットAを呼び出す フィルタA(認証のチェック)が実行される フィルタB(リクエストの文字コードの変換)が実行される フィルタC(ログへの書き込み)が実行される サーブレットAが実行される ``` このようにフィルタを多段にかけておくことが出来ますので、必要な機能を持ったフィルタを作成して設定しておけば、サーブレット自体は変更することなく、そして呼び出し元も気にすることなく様々な前処理が可能となります。 ## **1.フィルタの作成** フィルタは「javax.servlet.Filter」インタフェースを実装して作成します。このインタフェースで定義されているメソッドは3つで、それぞれが呼び出されるタイミングおよび処理内容は以下の通りです。 <table border="1"> <tr><td>init(javax.servlet.FilterConfig)</td><td>フィルタが初めて使用されるときに呼び出されます。「FilterConfig」は主にフィルタの初期設定値を読み出すために使用します。</td></tr> <tr><td>doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain) </td><td>フィルタの対象となるリソースが呼び出されたときに実行されます。「FilterChain」は次のフィルタやリクエストの対象であるJSPページやサーブレットの処理を実行するのに使用されます。</td></tr> <tr><td>destroy()</td><td>フィルタが破棄されるときに呼び出されます。何らかの後処理が必要な場合に実装します。</td></tr> </table> "**doFilter**"メソッドはFilterインターフェースを実装したフィルタクラスがフィルタとして呼び出された時に実行されるメソッドです。通常のサーブレットのdoGetメソッドやdoPostメソッドに相当します。<br> よってフィルタとして使うサーブレットは次のような構成になります。<br> ``` import java.io.*; import javax.servlet.*; import javax.servlet.Filter; import javax.servlet.FilterChain; public class FilterTest implements Filter{ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain){ try{ /* フィルタで行う処理 */ }catch (ServletException se){ }catch (IOException e){ } } public void init(FilterConfig filterConfig){ } public void destroy(){ } } ``` <br> ## **2.フィルタの設定** フィルタの設定も「WEB-INF/web.xml」で行います。フィルタの宣言と、フィルタを適応するURLの設定の2種類に分かれます。 ``` <?xml version="1.0" encoding="ISO-8859-1"?> <web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4"> <filter> <filter-name>Encoding</filter-name> <filter-class>filter.EncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>Encoding</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app> ``` #### **例** **EncodingFilter.java** ``` 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 final class EncodingFilter implements Filter { private String encoding = null; public void init(FilterConfig config) throws ServletException { encoding = config.getInitParameter("encoding"); } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException { System.out.println("フィルタ実行"); request.setCharacterEncoding(encoding); chain.doFilter(request, response); } public void destroy() { encoding = null; } } ``` **HelloWorld.java** ``` package filter; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/HelloWorld") public class HelloWorld extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { response.setContentType("text/html; charset=Shift_JIS"); PrintWriter out = response.getWriter(); System.out.println("HelloWorld"); out.println("<html>"); out.println("<head>"); out.println("<title>フィルタテスト</title>"); out.println("</head>"); out.println("<body>"); out.println("<p>Hello World!</p>"); out.println("</body>"); out.println("</html>"); } } ``` #### **実行結果** <!--graph10-2.png--> <img src="https://i.loli.net/2019/11/02/jfxgmKY6aHCcdt7.png" width="40%" /> <br> まず呼び出したサーブレットは普通に実行されています。 次にフィルタとして設定したサーブレットが実行されているか確認します。 <br> <!--graph10-3.png--> <img src="https://i.loli.net/2019/11/02/BckirJye1HvVf3P.png" width="40%" /> <br> Tomcatのstdoutログを確認すると、フィルターで記述した標準出力への出力が実行されていることが確認できました。HelloWorldクラスを呼び出すと、HelloWorldクラスが呼び出される前にEncodingFilterクラスが呼び出されていることになります。
content
戻る