目次
2. HandlerInterceptor インターフェースの分析
1: SpringMVC インターセプター
SpringMVC の Interceptor インターセプターは主に、指定されたユーザーリクエストをインターセプトし、対応する前処理と後処理を実行するために使用されます。そのインターセプトの時点は、「プロセッサ マッパーが、ユーザーから送信されたリクエストに従って実行されるプロセッサ クラスをマップし、プロセッサ クラスを実行するプロセッサ アダプタを見つけてから、プロセッサ アダプタがプロセッサを実行する前」です。もちろん、プロセッサ マッパーが実行されるプロセッサ クラスをマップすると、インターセプタとプロセッサはプロセッサ実行チェーンに結合され、中央スケジューラに返されます。
1. インターセプターの概要
(1) インターセプターの適用シナリオ
リクエストとレスポンスの追加処理、リクエストとレスポンスのプロセスにおける前処理、後処理、最終処理の追加。主に次のシナリオで使用されます。
① ロギング:リクエスト情報を記録するログです。
②権限チェック:ログインチェックなど。
③ パフォーマンステスト: テストメソッドの実行時間。
(2) インターセプターの実行原理
①preHandle():リクエストが処理される前に動作します;前処理。
②postHandle():リクエストが処理された後、結果がレンダリングされる前に、操作によって応答結果が変更される可能性があります (後処理)。
③afterCompletion:すべてのリクエストとレスポンスが完了した後、後続作業を実行し、オブジェクトをクリーンアップし、リソースをクローズし、最終処理を行います。
(3) インターセプタ実装の 2 つの方法
① HandlerInterceptorAdapter [ハンドラーインターセプトアダプター]の親クラスを継承します。
② HandlerInterceptor[ハンドラーインターセプター]インターフェースの実装 継承は単一継承のため、インターフェースの実装方法を使用することを推奨します。
2. HandlerInterceptor インターフェースの分析
カスタム インターセプターは HandlerInterceptor インターフェイスを実装する必要があり、インターフェイスには次の 3 つのメソッドが含まれています。
(1)プリハンドル
このメソッドは、ハンドラー メソッドが実行される前に実行されます。戻り値はブール型で、 trueの場合はプロセッサメソッドが即時に実行され、afterCompletion() メソッドは特別なメソッドスタックに置かれて実行されます。
(2)ポストハンドル
このメソッドは、ハンドラー メソッドの実行後に実行されます。最終的にハンドラーメソッドが実行されない場合、メソッドは実行されません。このメソッドはプロセッサメソッドの実行後に実行され、メソッドパラメータにModelAndViewが含まれるため、プロセッサメソッドの処理結果データを変更したり、ジャンプ方向を変更したりすることができます。
(3)完成後
preHandle() メソッドが true を返すと、メソッドは特別なメソッド スタックに配置され、リクエストに応じたすべての作業が完了するまでメソッドは実行されません。つまり、このメソッドは、中央スケジューラが応答ページをレンダリング (データを埋め込んだ) 後に実行されますが、この時点では、ModelAndView の操作は応答には役立ちません。afterCompletion は、Controller メソッドへのデータの追加など、リソースをクリアするために最後に実行されたメソッドです。
3. カスタム インターセプターは権限検証を実装します。
(1) ログイン方法を変換し、権限検証用のセッションにユーザー情報を格納する
詳細:ログイン インターフェイスの login.jsp が /login または /login.action にジャンプするかどうかに注意する必要があります。アクションの有無によって、インターセプタの exclude-mapping のパスが .action の有無にかかわらず通過するかどうかが直接決まります。
package com.bjpowernode.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
@Controller
public class WebInfAction {
// 首先要跳转到登录页面
@RequestMapping("/showLogin")
public String submit(){
System.out.println("访问login.jsp进行登录");
return "login";
}
// 跳转到login.jsp后,在进行判断
@RequestMapping("/login")
public String login(String name, String pwd, HttpServletRequest request){ // 与前端保持一致,提交的数据自动吸过来
if ("root".equalsIgnoreCase(name) && "123".equalsIgnoreCase(pwd)){
// 在session中存储用户信息(把name存进去),用于权限验证
request.getSession().setAttribute("user",name);
return "main";
}else {
request.setAttribute("msg","用户名或者密码不正确");
return "login";
}
}
}
(2) インターセプタの機能を開発し、HandlerInterceptorインタフェースを実装し、preHandle()メソッドを書き換える
package com.bjpowernode.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LoginInterceptor implements HandlerInterceptor {
// 重写preHandle方法
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 是否登录的判断
if(request.getSession().getAttribute("user") == null){ // 能取出来,表示登录过
// 没有登录,打回到登录的页面,并给出提示
request.setAttribute("msg","请先去登录!");
request.getRequestDispatcher("WEB-INF/jsp/login.jsp").forward(request,response);
return false;
}
// 如果登录过,就放行往下走
return true;
}
}
(3) springmvc.xmlファイルにインターセプタを登録します
インターセプター チェーンはインターセプター内で構成でき、レイヤーごとにチェックされます。ここでは 1 つだけ構成する必要があり、合計 3 つの部分を構成します。
① インターセプトするリクエストをマップします。通常はすべてインターセプトに設定されます。
②次にリクエストを解除するように設定します。
③特定のインターセプタの機能を実装するクラスを設定します。
<!--注册拦截器-->
<mvc:interceptors>
<mvc:interceptor>
<!--映射要拦截的请求-->
<mvc:mapping path="/**"/>
<!--配置要放行的请求-->
<mvc:exclude-mapping path="/showLogin"/><!--登录的页面-->
<mvc:exclude-mapping path="/login"/><!--登录验证的页面-->
<!--配置具体的拦截器实现功能的类-->
<bean class="com.bjpowernode.interceptor.LoginInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
(4) テスト:
ログインする前に、showMain または showIndex がわかっていますが、直接アクセスはアクセスできず、ブロックされています。
ログインに成功した後、現在のセッションを閉じるのではなく、ウィンドウを再度開くと、直接アクセスできるようになります。