前回の記事では Filter フィルターの使用方法を紹介しましたが、フィルターについて言及するときは、インターセプターと呼ばれるもう 1 つのことについても言及する必要があります。両者の機能は似ており、どちらもリクエストを傍受する機能を実現できますが、実は両者には非常に大きな違いがあります。この記事では、インターセプターの使用方法を学びましょう。
初心者で、これまでの SpringBoot 記事シリーズを読んでいない場合は、少なくともこれを読むことをお勧めします。
SpringBoot (4) SpringBoot はシンプルな server_springboot を構築します。service_heart を毒するブログ - CSDN 博客
最初から最後まで体系的に学びたい場合は、私の SpringBoot コラムに注目して更新し続けてください。
目次
1.インターセプターインターセプター
インターセプターはフィルターと非常によく似た機能を持っており、フィルターでできることはインターセプターでできること、あるいはそれ以上です。
Filter は Servlet の概念またはコンポーネントであり、Interceptor は Spring の概念またはコンポーネントです。Web 開発を行うときに、最も原始的なのは Spring や SpringBoot ではなく、Jsp + サーブレットを使用することであることは誰もが知っています (私が 3 年生のときにコンピューター室で Tomcat とサーブレットを設定したことを今でも覚えています...)。Spring とその後の SpringBoot はどちらも開発を簡素化するように設計されており、ここでは 2 つを詳細に比較しません。
同様に、インターセプターはクライアントとサーバーの間にあるコンポーネントであり、フィルターと同様に 0 から複数の値を持つことができます。
2. カスタムインターセプター
SpringBoot はインターセプターのサポートを提供しており、非常に使いやすいです。まず、HandlerInterceptor インターフェイスを実装してインターセプターを作成します。ここでは、インターセプターの実装のみがシミュレートされており、非常に単純なロジックが記述されています。リクエスト文字列に「sb」が含まれている場合はインターセプトされ、そうでない場合は解放されます。
package com.zhaojun.server.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("拦截器处理中...");
String queryString = request.getQueryString();
if (queryString.contains("sb")) {
System.out.println("拦截");
return false;
}
System.out.println("放行");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("拦截器处理结束...");
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("请求结束...");
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
}
次に、インターセプターを構成し、Config クラスを作成し、WebMvcConfigurer インターフェイスを実装して、@Configuration アノテーションを追加する必要があります。
package com.zhaojun.server.interceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class MyWebMvcConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor())
.addPathPatterns("/login");
}
}
3. インターセプターが有効であることを確認する
次に、インターセプターが機能するかどうかをテストします。まず、sb を含まない URL を使用してhttp://localhost:8080/login?name=zj&phone=156532890870&password=123456 をリクエストします。
コード実行のプロセスを見てください。
最初に preHandle に到達し、特定の文字 sb が含まれていないため解放されることがわかります。次に、postHandle と afterCompletion に順番に進みます。そして、前の記事で引き続きフィルターを書いたので、注意深い人ならインターセプターの前にフィルターが実行されることがわかります。
次に、特殊文字 sb を含む URL を使用してリクエストを行います。http://localhost:8080/login?name=sb&phone=156532890870&password=123456
特定の文字 sb が含まれているため、preHandle で正常にインターセプトされていることがわかります。このようにインターセプトは成功しているので、当然その後のpostHandlleやafterCompletionは実行されません。
4 つ、複数のインターセプター
フィルターを学習するときは、複数のフィルターを設定できます。前述したように、インターセプターには 0 から複数の値を含めることができます。次に、別のインターセプターを作成します。コードは最初のインターセプターを直接コピーします。実行プロセスを確認してください。
package com.zhaojun.server.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Interceptor2 implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("拦截器2处理中...");
String queryString = request.getQueryString();
if (queryString.contains("sb")) {
System.out.println("拦截");
return false;
}
System.out.println("放行");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("拦截器2处理结束...");
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("请求结束2...");
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
}
これに応じて、このインターセプターを Config クラスに追加する必要があります。
package com.zhaojun.server.interceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class MyWebMvcConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor())
.addPathPatterns("/login");
registry.addInterceptor(new Interceptor2());
}
}
sb を含まない URL と sb を含む URL をそれぞれ使用してリクエストし、実行プロセスは次のようになります。
いくつかのルールを確認できます。簡単な概要は次のとおりです。
(1) 最初のインターセプタが preHandle でインターセプトしなかった場合、2 番目のインターセプタの preHandle まで順次実行されます。
(2) 2 番目のインターセプタが preHandle でインターセプトされなかった場合は、postHandle と afterCompletion を逆の順序で実行します。
(3) 最初のインターセプタがインターセプトせず、2 番目のインターセプタがインターセプトする場合、最初のインターセプタの afterCompletion が直接実行されます。
(4) 最初のインターセプタがインターセプトした場合、後続のインターセプタは再度実行されません。