Javaのフィルタの詳しい説明

高洛峰
リリース: 2017-02-08 11:41:05
オリジナル
1600 人が閲覧しました

フィルターの概要

フィルターは、サーブレットテクノロジーの中で最も実用的なテクノロジーであり、Web サーバーによって管理されるすべての Web リソース (JSP、サーブレット、静的 HTML など) を管理します。いくつかの特別な機能を実現するために、ファイルなどがインターセプトされます。たとえば、URL レベルの権限アクセス制御、機密語彙のフィルタリング、応答情報の圧縮などの高度な機能を実装できます。

これは主にユーザーリクエストの前処理に使用され、HttpServletResponse の後処理もできます。 Filter を使用する完全なプロセス: Filter はユーザー リクエストを前処理し、次にそのリクエストを処理のためにサーブレットに渡して応答を生成し、最後に Filter がサーバーの応答を後処理します。

フィルター関数

クライアントの HttpServletRequest がサーブレットに到達する前にインターセプトします。必要に応じて HttpServletRequest を確認し、HttpServletRequest ヘッダーとデータを変更します。

HttpServletResponse がクライアントに到達する前にインターセプトします。必要に応じて HttpServletResponse を確認し、HttpServletResponse ヘッダーとデータを変更します。

Filter を使用してインターセプト機能を実装する方法

Filter インターフェイスには doFilter メソッドがあります。開発者が Filter を作成し、どの Web リソースをインターセプトするかを設定すると、WEB サーバーは最初にそのサービス メソッドを呼び出します。したがって、このメソッドにコードを記述することで、次の目的を達成できます:

ターゲット リソースを呼び出す前にコードを実行させます。

ターゲットリソースを呼び出すかどうか (つまり、ユーザーに Web リソースへのアクセスを許可するかどうか)。

Web サーバーが doFilter メソッドを呼び出すと、filterChain オブジェクトが渡されます。filterChain オブジェクトは、フィルター インターフェイスで最も重要なオブジェクトです。また、開発者は、このメソッドを呼び出すかどうかを決定できます。メソッドを呼び出すと、Web サーバーは Web リソースのサービス メソッドを呼び出します。つまり、Web リソースがアクセスされます。それ以外の場合、Web リソースはアクセスされません。

2 つのステップでのフィルター開発

Filter インターフェースを実装する Java クラスを作成し、その doFilter メソッドを実装します。

web.xml ファイル内の および 要素を使用して、作成されたフィルター クラスを登録し、インターセプトできるリソースを設定します。

web.xml 構成の各ノードの概要:

フィルターを指定します。

この要素の内容を空にすることはできません。

要素は、フィルターの完全修飾クラス名を指定するために使用されます。

要素は、フィルターの初期化パラメーターを指定するために使用されます。 はパラメーターの値を指定します。 。

フィルターでは、FilterConfig インターフェイス オブジェクトを使用して初期化パラメーターにアクセスできます。

要素は、フィルターがインターセプトするリソースを設定するために使用されます。フィルターによってインターセプトされるリソースは、サーブレット名とリソース アクセスのリクエスト パスの 2 つの方法で指定できます。 サブ要素は、フィルターの登録名を設定するために使用されます。この値は、 要素で宣言されたフィルターの名前である必要があります

フィルターによってインターセプトされるリクエスト パス (フィルターに関連付けられた URL パターン) を設定します

フィルターによってインターセプトされたサーブレットの名前を指定します。

フィルタによってインターセプトされたリソースがサーブレット コンテナによって呼び出される方法を指定します。デフォルトは REQUEST です。ユーザーは、複数の サブ要素を設定して、リソースの複数の呼び出しメソッドをインターセプトする Filter を指定できます。

サブ要素で設定できる値とその意味

REQUEST: ユーザーがページに直接アクセスすると、Web コンテナがフィルターを呼び出します。 RequestDispatcher の include() メソッドまたは forward() メソッドを通じてターゲット リソースにアクセスする場合、このフィルターは呼び出されません。

INCLUDE: RequestDispatcher の include() メソッドを通じてターゲット リソースにアクセスすると、このフィルターが呼び出されます。それ以外の場合、フィルターは呼び出されません。

FORWARD: RequestDispatcher の forward() メソッドを通じてターゲット リソースにアクセスすると、このフィルターが呼び出されます。それ以外の場合、このフィルターは呼び出されません。

エラー: このフィルターは、ターゲット リソースが宣言型例外処理メカニズムを通じて呼び出された場合に呼び出されます。それ以外の場合、フィルターは呼び出されません。

フィルターチェーン

Web アプリケーションでは、複数のフィルターを開発および作成できます。これらのフィルターの組み合わせはフィルター チェーンと呼ばれます。

Web サーバーは、フィルターが web.xml ファイルに登録されている順序に基づいて、最初に呼び出すフィルターを決定します。最初のフィルターの doFilter メソッドが呼び出されるとき、Web サーバーはフィルターを表す FilterChain オブジェクトを作成します。チェーンしてメソッドに渡します。 doFilter メソッドで、開発者が FilterChain オブジェクトの doFilter メソッドを呼び出すと、Web サーバーは FilterChain オブジェクトに別のフィルタがあるかどうかを確認し、存在する場合は 2 番目のフィルタが呼び出されます。呼ばれる。

フィルターのライフサイクル

public void init(FilterConfig filterConfig) throws ServletException;//初始化
ログイン後にコピー

私たちが作成したサーブレット プログラムと同様に、フィルターの作成と破棄は WEB サーバーの責任です。 Web アプリケーションが開始されると、Web サーバーは Filter のインスタンス オブジェクトを作成し、その init メソッドを呼び出し、web.xml 構成を読み取り、オブジェクトの初期化関数を完了します。これにより、後続のユーザー要求 (フィルター オブジェクト) のインターセプトの準備が整います。は 1 回だけ作成され、init メソッドは 1 回だけ実行されます)。開発者は、init メソッドのパラメーターを通じて、現在のフィルター構成情報を表す FilterConfig オブジェクトを取得できます。

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException;//拦截请求
ログイン後にコピー

このメソッドで実際のフィルタリング操作が完了します。クライアントがフィルタに関連付けられた URL へのアクセスを要求すると、サーブレット フィルタは最初に doFilter メソッドを実行します。 FilterChain パラメーターは、後続のフィルターにアクセスするために使用されます。

public void destroy();//销毁
ログイン後にコピー

フィルター オブジェクトは作成後にメモリ内に常駐し、Web アプリケーションが削除されるかサーバーが停止されると破棄されます。 Web コンテナが Filter オブジェクトをアンロードする前に呼び出されます。このメソッドは、フィルターのライフサイクルで 1 回だけ実行されます。この方法では、フィルタが使用していたリソースを解放することができます。

FilterConfig インターフェイス

フィルターを構成する場合、ユーザーはフィルターのいくつかの初期化パラメーターを構成できます。Web コンテナーが Filter オブジェクトをインスタンス化し、その init メソッドを呼び出すと、フィルターの初期化パラメーターをカプセル化する filterConfig オブジェクトが渡されます。したがって、開発者がフィルターを作成する場合、filterConfig オブジェクトのメソッドを通じて次のコンテンツを取得できます:

String getFilterName();//得到filter的名称。 String getInitParameter(String name);//返回在部署描述中指定名称的初始化参数的值。如果不存在返回null. Enumeration getInitParameterNames();//返回过滤器的所有初始化参数的名字的枚举集合。 public ServletContext getServletContext();//返回Servlet上下文对象的引用。
ログイン後にコピー

フィルターの使用例

フィルターを使用してユーザー ログインのセキュリティ制御を検証する

少し前にプロジェクトのメンテナンスに参加しましたユーザーがシステムからログアウトした後も、アドレス バーに移動して、URL に従ってシステム応答ページにアクセスできます。確認したところ、ユーザーのログインを検証するためにリクエストがフィルタリングされていないことがわかりました。フィルタを追加して問題を解決してください。

まずWebで

<filter>
    <filter-name>SessionFilter</filter-name>
    <filter-class>com.action.login.SessionFilter</filter-class>
    <init-param>
        <param-name>logonStrings</param-name><!-- 对登录页面不进行过滤 -->
        <param-value>/project/index.jsp;login.do</param-value>
    </init-param>
    <init-param>
        <param-name>includeStrings</param-name><!-- 只对指定过滤参数后缀进行过滤 -->
        <param-value>.do;.jsp</param-value>
    </init-param>
    <init-param>
        <param-name>redirectPath</param-name><!-- 未通过跳转到登录界面 -->
        <param-value>/index.jsp</param-value>
    </init-param>
    <init-param>
        <param-name>disabletestfilter</param-name><!-- Y:过滤无效 -->
        <param-value>N</param-value>
    </init-param></filter><filter-mapping>
    <filter-name>SessionFilter</filter-name>
    <url-pattern>/*</url-pattern></filter-mapping>
ログイン後にコピー

を設定します。

中国語の文字化けフィルターを防止

プロジェクトがSpringフレームワークを使用している場合。フロントエンド JSP ページと JAVA コードのエンコードに異なる文字セットが使用されている場合、フォームから送信されたデータやアップロード/ダウンロードされた中国語名のファイルが文字化けするため、このフィルターを使用できます。

package com.action.login;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;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpServletResponseWrapper;/**
 *    判断用户是否登录,未登录则退出系统
 */public class SessionFilter implements Filter {    public FilterConfig config;    public void destroy() {        this.config = null;
    }    public static boolean isContains(String container, String[] regx) {        boolean result = false;        for (int i = 0; i < regx.length; i++) {            if (container.indexOf(regx[i]) != -1) {                return true;
            }
        }        return result;
    }    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest hrequest = (HttpServletRequest)request;
        HttpServletResponseWrapper wrapper = new HttpServletResponseWrapper((HttpServletResponse) response);

        String logonStrings = config.getInitParameter("logonStrings");        // 登录登陆页面
        String includeStrings = config.getInitParameter("includeStrings");    // 过滤资源后缀参数
        String redirectPath = hrequest.getContextPath() + config.getInitParameter("redirectPath");// 没有登陆转向页面
        String disabletestfilter = config.getInitParameter("disabletestfilter");// 过滤器是否有效

        if (disabletestfilter.toUpperCase().equals("Y")) {    // 过滤无效
            chain.doFilter(request, response);            return;
        }
        String[] logonList = logonStrings.split(";");
        String[] includeList = includeStrings.split(";");        if (!this.isContains(hrequest.getRequestURI(), includeList)) {// 只对指定过滤参数后缀进行过滤
            chain.doFilter(request, response);            return;
        }        if (this.isContains(hrequest.getRequestURI(), logonList)) {// 对登录页面不进行过滤
            chain.doFilter(request, response);            return;
        }

        String user = ( String ) hrequest.getSession().getAttribute("useronly");//判断用户是否登录
        if (user == null) {
            wrapper.sendRedirect(redirectPath);            return;
        }else {
            chain.doFilter(request, response);            return;
        }
    }    public void init(FilterConfig filterConfig) throws ServletException {
        config = filterConfig;
    }
}
ログイン後にコピー

Spring+HibernateのOpenSessionInViewFilterはセッションの切り替えを制御します

hibernate+springを併用した場合、lazy=true(遅延読み込み)が設定されている場合、データを読み込む際、親データを読み取った後、hibernateは自動的にセッションを閉じますしたがって、それに関連付けられたデータとサブデータを使用したい場合、システムは Lazyinit エラーをスローします。この場合、Spring が提供する OpenSessionInViewFilter フィルターを使用する必要があります。

OpenSessionInViewFilter は主に、リクエストがすべてのページをクライアントに送信するまでセッション状態を維持し、リクエストが完了するまでセッションを閉じないため、読み込みの遅延によって引き起こされる問題を解決します。

注: OpenSessionInViewFilter 構成は、struts2 構成の前に記述する必要があります。 Tomcat コンテナーはフィルターを順番にロードするため、構成ファイルが最初に struts2 フィルター構成を書き込み、次に OpenSessionInViewFilter フィルター構成を書き込むと、アクションが Spring によって管理されていないデータを取得するときに、ロード順序によってセッションが切断されます。

<filter>
    <filter-name>encoding</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name><!--用来指定一个具体的字符集-->
        <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
        <param-name>forceEncoding</param-name><!--true:无论request是否指定了字符集,都是用encoding;false:如果request已指定一个字符集,则不使用encoding-->
        <param-value>false</param-value>
    </init-param></filter><filter-mapping>
    <filter-name>encoding</filter-name>
    <url-pattern>/*</url-pattern></filter-mapping>
ログイン後にコピー

Struts2 web.xml 構成

プロジェクトで Struts2 を使用するには、リクエストをインターセプトし、処理のために Struts2 アクションに転送するために web.xml でフィルターを構成する必要もあります。

注: Struts2 のバージョンが 2.1.3 より前の場合、フィルターは org.apache.struts2.dispatcher.FilterDispatcher を使用します。それ以外の場合は、org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter を使用します。 Struts2.1.3 以降、ActionContextCleanUp フィルターは廃止され、対応する機能が StrutsPrepareAndExecuteFilter フィルターに含まれるようになります。

3 つの初期化パラメータ設定:

config パラメータ: ロードする設定ファイルを指定します。カンマ区切り。

actionPackages パラメーター: Action クラスが配置されるパッケージ領域を指定します。カンマ区切り。

configProviders パラメーター: ConfigurationProvider インターフェイス クラスを実装する必要があるカスタム構成ファイル プロバイダー。カンマ区切り。

<filter><!-- lazy loading enabled in spring -->
    <filter-name>OpenSessionInViewFilter</filter-name>
    <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
    <init-param>
        <param-name>sessionFactoryBeanName</param-name><!-- 可缺省。默认是从spring容器中找id为sessionFactory的bean,如果id不为sessionFactory,则需要配置如下,此处SessionFactory为spring容器中的bean。 -->
        <param-value>sessionFactory</param-value>
    </init-param>
    <init-param>
        <param-name>singleSession</param-name><!-- singleSession默认为true,若设为false则等于没用OpenSessionInView -->
        <param-value>true</param-value>
    </init-param></filter><filter-mapping>
    <filter-name>OpenSessionInViewFilter</filter-name>
    <url-pattern>*.do</url-pattern></filter-mapping>
ログイン後にコピー

Java のフィルターの詳細な説明と関連記事については、PHP 中国語 Web サイトに注目してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート