フィルターの紹介
しかし、それだけではありません。サーブレットがそれほど単純だとは思っていませんよね?
すでに分析したサーブレットに加えて、いわゆる「ユーティリティ サーブレット」、つまりフィルターもあります。これらはサーブレットに非常に似ていますが、主な仕事はサーブレットによるリクエストの処理を支援することです。
フィルターは秘書のようなもので、サーブレットはディレクターのようなものです。文書は局長の机に届く前に秘書の手を通過します。そして、ディレクターが署名した後、それは、たとえばすでに発信通信として再び秘書に送られます。
このような秘書は、ディレクターへのリクエストの一部 (スパムなど) を拒否できます。あるいは、彼が知っている質問に対して標準的な答えを返します(「監督はその場にいません」)。等々。さらに、そのような秘書が複数存在する可能性があります。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 つの方法でこれを行うことができます。
redirectforward
すでに分析済みですが、便宜上もう一度言います。
呼び出し経由でリダイレクトするとresponse.sendRedirect("link")、サーバーは応答302と指定したリンクをブラウザ (クライアント) に送り返します。そしてブラウザは、サーバーの応答を分析した後、渡されたリンクをダウンロードします。つまり、ブラウザ内のリンクが新しいリンクに変わります。
call を介して転送する場合requestDispatcher.forward()、コンテナ内で新しいリクエストが作成され、サーブレットはその応答をサーブレットの応答としてブラウザ (クライアント) に送信します。この場合、ブラウザは新しいサーブレットから応答を受け取りますが、ブラウザ内のリンクは変更されません。
GO TO FULL VERSION