フィルターの紹介
しかし、それだけではありません。サーブレットがそれほど単純だとは思っていませんよね?
すでに分析したサーブレットに加えて、いわゆる「ユーティリティ サーブレット」、つまりフィルターもあります。これらはサーブレットに非常に似ていますが、主な仕事はサーブレットによるリクエストの処理を支援することです。
フィルターは秘書のようなもので、サーブレットはディレクターのようなものです。文書は局長の机に届く前に秘書の手を通過します。そして、ディレクターが署名した後、それは、たとえばすでに発信通信として再び秘書に送られます。
このような秘書は、ディレクターへのリクエストの一部 (スパムなど) を拒否できます。あるいは、彼が知っている質問に対して標準的な答えを返します(「監督はその場にいません」)。等々。さらに、そのような秘書が複数存在する可能性があります。1 人はすべてのディレクターのスパムを一度にフィルタリングでき、もう 1 人は異なるディレクター間でリクエストを転送できます。
フィルターも同様に機能します。
クラス Filter、FilterChain、FilterConfig
フィルターはサーブレットとよく似ていますが、いくつかの小さな違いがあります。独自のフィルターを作成するには、 から継承する必要がありますjavax.servlet.Filter
。
フィルターにはメソッドinit()
ともありますdestroy()
。service()
フィルターにはメソッドの代わりに がありますdoFilter()
。さらに、独自のクラス FilterConfig もあります。フィルターは、web.xml ファイルまたは @WebFilter アノテーションを介してサーブレットにも追加されます。
メソッドのリスト:
メソッド | 説明 | |
---|---|---|
1 | init(FilterConfig config) |
フィルタの初期化 |
2 | destroy() |
フィルターのアンロード |
3 | doFilter(ServletRequest , ServletResponse, FilterChain) |
リクエスト処理(フィルタリング) |
サーブレットとフィルターの違いは何ですか?
複数のフィルターが存在し、リクエスト (およびレスポンス) を順番に処理します。それらはいわゆるチェーンに結合され、それらのための特別なクラスさえありますFilterChain
。
メソッドでリクエストを処理した後、チェーン内の次のフィルターのdoFilter()
メソッドを呼び出す必要があります。doFilter()
例:
public class MyFilter implements Filter {
public void init(FilterConfig arg0) throws ServletException {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws Exception {
PrintWriter out = resp.getWriter();
out.print("Adding something before the body of the response");
chain.doFilter(req, resp); // call the next filter in the chain
out.print("Adding something after the body of the response");
}
public void destroy() {
}
}
実際には、そのように応答本文を追加することはできません。正式には、フィルタとサーブレットは互いに独立しており、個別に変更できます。これらは、異なる開発者によって異なる時期に作成される可能性があります。フィルター関数は単なるサービス関数です。次に例を示します。
- すべての受信リクエスト (および応答) をログに記録する
- データ圧縮
- データの暗号化 (および復号化)
- データ検証のリクエスト
- 必要なヘッダーを追加/削除します
- リダイレクトリクエスト
- アクセス制御(ユーザーがログインしているかどうかの確認)
RequestDispatcher クラス
メソッド内でフィルタを実行しているときに、doFilter()
別のサーブレットを呼び出すことが必要になる場合があります。これを行うために、コンテナには特別なオブジェクトがありますRequestDispatcher
。
次の 2 つの方法で取得できます。
- オブジェクトのところで
HttpServletRequest
- オブジェクトのところで
ServletContext
このオブジェクトを使用して、既存のリクエストを別のサーブレットにリダイレクトできます。たとえば、ユーザーが認証されていないことが判明したため、認証されたページをユーザーに表示したいとします。または、サーバーでエラーが発生したので、ユーザーにエラーページを表示したいと思います:)
public class HelloServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws Exception {
String path = "/error.html";
ServletContext servletContext = this.getServletContext();
RequestDispatcher requestDispatcher = servletContext.getRequestDispatcher(path);
requestDispatcher.forward(request, response);
}
}
RequestDispatcher
フィルターから呼び出すこともできます。
public class MyFilter implements Filter {
public void init(FilterConfig arg0) throws ServletException {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws Exception {
String path = "/error.html";
ServletContext servletContext = req.getServletContext();
RequestDispatcher requestDispatcher = servletContext.getRequestDispatcher(path);
requestDispatcher.forward(req, resp);
}
public void destroy() {
}
}
リクエストはメソッド内で処理され、使用後にforward()
呼び出す必要がないことに注意してください。doFilter()
RequestDispatcher
リダイレクトと転送の比較
そして、もう一つ重要な点があります。ユーザーをサーブレット内の別の URI にリダイレクトする場合は、次の 2 つの方法でこれを行うことができます。
redirect
forward
すでに分析済みですが、便宜上もう一度言います。
呼び出し経由でリダイレクトするとresponse.sendRedirect("link")
、サーバーは応答302
と指定したリンクをブラウザ (クライアント) に送り返します。そしてブラウザは、サーバーの応答を分析した後、渡されたリンクをダウンロードします。つまり、ブラウザ内のリンクが新しいリンクに変わります。
call を介して転送する場合requestDispatcher.forward()
、コンテナ内で新しいリクエストが作成され、サーブレットはその応答をサーブレットの応答としてブラウザ (クライアント) に送信します。この場合、ブラウザは新しいサーブレットから応答を受け取りますが、ブラウザ内のリンクは変更されません。
GO TO FULL VERSION