記事ディレクトリ
フィルターはサーブレット仕様に属しており、Spring に固有のものではありません。フィルターは主にリクエストをインターセプトし、いくつかのビジネス ロジック操作を実行し、リクエストを他のフィルターまたは対応するサーブレットに引き続き配布できるかどうかを決定するために使用されます。
フィルターワークフロー
-
フィルターを入力し、関連するビジネス ロジックを実行します
-
判定に失敗した場合はサーブレットにリクエストを送信せずに直接リターンする
-
合格と判定された場合は、次のフィルタに進みます
すべてのフィルターが合格した場合は、サーブレット ロジックに入り、サーブレットが実行された後、フィルターに戻り、最後にリクエスターに戻ります。
カスタムフィルターの使用方法
Spring でのフィルターのさまざまな使用方法はすべて網羅されています。FilterRegistrationBean はフィルターをラップし、最後にそれをサーブレット コンテナーに登録します。
1. @WebFilter+@ServletComponentScan
SpringBootApplication に @ServletComponentScan アノテーションを追加し、Filter に @WebFilter アノテーションを追加します。
この方法の欠点: フィルター間の優先順位を設定できません。
@WebFilter+@ServletComponentScan メソッドでは、@Order アノテーションを使用してフィルターの優先度を指定できません。優先度はデフォルト値 Ordered.LOWEST_PRECEDENCE (2147483647) を使用します。同じ優先度の場合は、名前の順序に従って決定されます。
手順
1. SpringBootApplication で @ServletComponentScan アノテーションを使用します
@ServletComponentScan
@SpringBootApplication
public class SpringbootApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootApplication.class, args);
}
}
2. フィルターに @WebFilter アノテーションを使用する
@WebFilter(urlPatterns = {
"/test3"})
public class MyFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
System.out.println("======= MyFilter =======");
filterChain.doFilter(request,response);
}
}
@WebFilter
@WebFilter は、クラスをフィルターとして宣言するために使用されます。
WebFilter アノテーションの主な属性は次のとおりです。
属性名 | タイプ | 説明 |
---|---|---|
フィルタ名 | 弦 | フィルターの name 属性を指定します (springbean もこの名前を使用します)。これは <filter-name> と同等です。 |
URLパターン | 弦[] | フィルタの URL 一致パターンのセットを指定します。<url-pattern> と同等 |
価値 | 弦[] | この属性は urlPatterns 属性と同等ですが、両方を同時に使用しないでください。 |
セブレット名 | 弦[] | フィルタを使用するサーブレットを指定します。値は、@WebServlet の name 属性の値、または web.xml の <servlet-name> です。 |
ディスパッチャの種類 | ディスパッチャータイプ[] | 一連のフィルタの転送モードを指定します。特定の値には、ASYNC、ERROR、FORWARD、INCLUDE、REQUEST、デフォルトの REQUEST が含まれます。 |
initParams | WebInitParam[] | <init-param> に相当する一連のフィルタ初期化パラメータを指定します。 |
非同期サポートあり | ブール値 | フィルターが非同期操作モードをサポートするかどうかを宣言します。<async-supported> タグと同等です。 |
説明 | 弦 | フィルターの説明。<description> に相当します。 |
表示名 | 弦 | フィルタの表示名は通常ツールで使用され、<display-name> と同等です。 |
@ServletComponentScan
SpringBoot プロジェクトでは、@WebServlet、@WebFilter、および @WebListener の 3 つのアノテーションはデフォルトではスキャンされません。通常、これら 3 つのアノテーションのスキャンを示すために @ServletComponentScan アノテーションが SpringBootApplication に追加されます。
@ServletComponentScan は、コードを追加することなく、Servlet (コントローラー)、Filter (フィルター)、および Listener (リスナー) を Spring コンテナーに自動的に登録できます。
- サーブレット: @WebServlet アノテーションによって定義
- フィルター: @WebFilter アノテーションによって定義
- リスナー: @WebListener アノテーションによって定義
FAQ分析
1. @WebFilte のみを使用します。フィルターは有効になりません。
WebFilter はアノテーションに属し、Servlet3+ に属し、Spring 自体とは何の関係もないため、デフォルトでは Spring はこのアノテーションを認識しません。
2. @WebFilter+@Component: 設定したフィルター条件が有効にならない
上記と同様、Spring は @WebFilter アノテーションを認識しないため、アノテーション設定の属性は無意味です (例: フィルターする URL の指定)。
このメソッドは実際には @Component アノテーションを追加するだけと同等であり、この時点でフィルターは有効になりますが、フィルター条件はなく、すべての URL がフィルターされます。
3. @WebFilter+@Component+@ServletComponentScan: フィルターは 2 回呼び出されます。
- 1 回: @WebFilter+@ServletComponentScan、SpringBean によって管理され、フィルターが有効になり、@WebFilter によって構成された属性に従ってフィルター処理されます。
- 2 回目: @Component は再び SpringBean によって管理され、フィルターが有効になり (上記と同じ Bean ではありません)、すべての URL がフィルターされます。
4. @WebFilter+@Order+@ServletComponentScan: フィルター優先度の設定が無効です
@WebFilter+@ServletComponentScan を通じて登録された場合、生成された FilterRegistrationBean は @Order アノテーションをチェックしないため、@Order アノテーションは有効になりません。
詳細は記事:@webFilterによる@Orderの不正使用についてをご参照ください。
2. @コンポーネント + @Order
Filter に @Component や @Order アノテーションを付加することで Spring で管理できるようになり、フィルタの実行順序を指定できるようになります。
この方法の欠点: すべての URL のみをフィルタリングでき、指定した URL を構成でフィルタリングできないことです。
手順
@Order(100)
@Component
public class MyFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
System.out.println("======= MyFilter =======");
filterChain.doFilter(request,response);
}
}
3. FilterRegistrationBean (推奨)
構成クラスを通じてフィルターの FilterRegistrationBean を直接定義し、それを管理のために SpringBean コンテナーに渡します。
この方法では、設定を通じて指定した URL をフィルタリングできるだけでなく、フィルタ間の優先順位も指定できます。
手順
public class MyFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
System.out.println("======= MyFilter =======");
filterChain.doFilter(request,response);
}
}
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean<MyFilter> filterRegistrationBean() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(myFilter());
registration.setName("myFilter");
registration.addUrlPatterns("/test3");
registration.setOrder(100);
return registration;
}
@Bean
public MyFilter myFilter() {
return new MyFilter();
}
}