Springboot Webプロジェクトの開発中、通常、リクエストのロギング、UAチェック、ユーザー権限の確認、違法なコンテンツのフィルタリングなどの機能など、リクエストとレスポンスのコンテンツのインターセプトをリクエストする必要があります。このとき、フィルターとインターセプターが送信されます。使用する。
この記事では、springbootがフィルターとインターセプターをどのように使用するか、および2つの違いを説明します。
この記事のナビゲーション
フィルタ
サーブレットフィルタは、要求と応答を動的にインターセプトして、要求または応答に含まれる情報を変換または使用できます。フィルターは、javax.servlet.Filterインターフェースを実装するJavaクラスです。javax.servlet.Filterインターフェースは3つのメソッドを定義します。
public interface Filter {
default void init(FilterConfig filterConfig) throws ServletException {
}
void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException;
default void destroy() {
}
}
シリアルナンバー | 方法と説明 |
---|---|
1 | doFilter メソッドは実際のフィルタリング操作を完了します。クライアントがフィルター設定と一致するURLを要求すると、サーブレットコンテナーはまずフィルターのdoFilterメソッドを呼び出します。FilterChainユーザーは、後続のフィルターにアクセスします。 |
2 | init Webアプリケーションが開始されると、WebサーバーはFilterのインスタンスオブジェクトを作成し、そのinitメソッドを呼び出し、web.xml構成を読み取り、オブジェクトの初期化関数を完了し、後続のユーザー要求(フィルターオブジェクト)のインターセプトを準備しますこれは一度だけ作成され、initメソッドは一度だけ実行されます)。開発者は、initメソッドのパラメーターを使用して、現在のフィルター構成情報を表すFilterConfigオブジェクトを取得できます。 |
3 | destroy サーブレットコンテナーは、フィルターインスタンスを破棄する前にこのメソッドを呼び出します。この場合、サーブレットフィルターが占有していたリソースが解放されます。 |
SpringBootはフィルターを使用します
単純なフィルターを定義します
@Slf4j
public class LogFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest req=(HttpServletRequest)servletRequest;
log.info(req.getRequestURI());
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
}
}
FilterRegistrationBeanを使用してフィルターを登録する
@Configuration
public class LogFilterConfiguration {
@Bean
public FilterRegistrationBean registrationBean(){
FilterRegistrationBean registrationBean=new FilterRegistrationBean();
registrationBean.setFilter(new LogFilter());
//匹配的过滤器
registrationBean.addUrlPatterns("/*");
//过滤器名称
registrationBean.setName("logFilter");
//过滤器顺序
registrationBean.setOrder(1);
return registrationBean;
}
}
Servlet3.0アノテーションを使用してフィルターを定義する
@WebFilter(urlPatterns = "/*",filterName = "authFiler")
@Slf4j
public class AuthFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
log.info("进行权限校验.........");
chain.doFilter(servletRequest,servletResponse);
}
}
2つの方法の違い:
- 注釈WebFilterは実行順序の属性を指定していません。実行順序はフィルターの名前に依存します。フィルターの名前は、フィルタークラス名に従って逆アルファベット順に並べ替えられます(構成されたフィルターの名前ではないことに注意してください)。
- @WebFilterによって指定されたフィルターの優先度は、FilterRegistrationBeanによって構成されたフィルターよりも高い
- FilterRegistrationBeanメソッドは、BeanをSpringBoot IOCコンテナーに注入できます
インターセプター
SpringBootインターセプターインターセプターと同様のオリエンテッドプログラミングのセクションとインフォームで、通知機能の拡張機能を追加するための動的プロキシーを使用します。たとえば、初期化プロセスでメソッドが実行される前に、後処理を実行するメソッドの後に実行されます。インターセプターのアイデアと同様に、違いはインターセプトの要求のみのインターセプターです。service()
AOP
Controller
HTTP
public interface HandlerInterceptor {
default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return true;
}
default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
}
default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
}
}
シリアルナンバー | 方法と説明 |
---|---|
1 | preHandle メソッドは、コントローラーがリクエストを処理するリクエストを受け取る前に実行されます。戻り値はブール値です。戻り値がtrueの場合、postHandle()メソッドとafterCompletion()メソッドが実行されます。falseが返された場合、実行は中断されます。 |
2 | postHandleは 、コントローラーが要求を処理した後、ModelAndViewが要求を処理する前に実行され、応答結果は変更できます。 |
3 | afterCompletion は、DispatchServletがこのリクエストを処理した後、つまりModelAndViewが生成された後に実行されます。 |
単純なインターセプターを定義する
@Slf4j
public class LogHandler implements HandlerInterceptor {
private NamedThreadLocal<Long> startTimeThreadLocal = new NamedThreadLocal<>("StopWatch-StartTime");
public LogHandler() {
super();
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
long beginTime = System.currentTimeMillis();//1、开始时间
startTimeThreadLocal.set(beginTime);//线程绑定变量(该数据只有当前请求的线程可见)
return true;//继续流程
}
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
long endTime = System.currentTimeMillis();
long beginTime = startTimeThreadLocal.get();//得到线程绑定的局部变量(开始时间)
long consumeTime = endTime - beginTime;
//3、消耗的时间
log.info(String.format("%s consume %d millis", request.getRequestURI(), consumeTime));
}
}
インターセプターの登録
@Configuration
public class HandlerConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LogHandler());
}
}
フィルターとインターセプターの違い
シリアルナンバー | 違い |
---|---|
1 | Filterはサーブレット仕様で、使用範囲はWebプログラムです。インターセプターはWebプログラムに限定されず、ApplicationおよびSwingプログラムでも使用できます。 |
2 | フィルターはサーブレット仕様で定義され、サーブレットコンテナーによってサポートされます。インターセプターはSpringコンテナー内にあり、Springフレームワークによってサポートされています |
3 | インターセプターはSpringのコンポーネントであり、Serviceオブジェクト、データソース、トランザクション管理、IOCを介したコンテナーへの注入など、Springのオブジェクトを使用できますが、フィルターはできません |
4 | フィルターはサーブレットの前後で機能し、インターセプターは例外がスローされる前後にメソッドに深く入ります。 |
5 | インターセプターは通常、Springbootプロジェクトで優先されます |
千マイルは単一のステップから始まります。これは、SpringBootチュートリアルシリーズの12番目の記事です。すべてのプロジェクトソースコードは、GitHubからダウンロードできます。