spring-mvcインターセプターの原理と例のデモンストレーション

spring-mvcインターセプター

   概要:

    spring-mvcインターセプターは主にHandlerInterceptorインターフェースを実装します。spring-mvc のコアDispatcherServletがメイン処理リクエストメソッドdoDispatchを実行すると、プロセッサーマッパーHandlerMappingは対応するハンドラー見つけ、リクエストオブジェクトのリクエストパスに従ってHandlerInterceptor実装クラスをラップします。 requset HandlerInterceptorChainにアセンブルすると、HandlerInterceptorChainは、ハンドラーの実行シーケンスに従って、各インターセプターの特定のメソッドを呼び出します。

   HandlerInterceptorインターセプターは、主に前処理メソッドのにリクエスト処理してインターセプトし、後処理メソッドのに処理実行します。特定のインターセプターの前処理が実行された場合、最終的な処理メソッドは前処理のいずれかです。割り込み要求またはエラーレポート。最終的な処理方法を実装する必要があります。

   DispatcherServletの簡略化されたメイン実行コードdoDispatch()を見てみましょう

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
		HttpServletRequest processedRequest = request;
		HandlerExecutionChain mappedHandler = null;
		try {
			ModelAndView mv = null;
			Exception dispatchException = null;
			try {
                // 由HandlerMapping 找到handle并包装拦截器组装成HandlerExecutionChain
				mappedHandler = getHandler(processedRequest);

				// 因为handler可以是任意类型,因此需要由一个HandlerAdapter来包装调用
				HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
				
                // 前置处理链
				if (!mappedHandler.applyPreHandle(processedRequest, response)) {
					return;
				}
                
                // 实际调用方法
        		mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

                // 后置处理链
				mappedHandler.applyPostHandle(processedRequest, response, mv);
			}
			catch (Exception ex) {
				dispatchException = ex;
			}
            // 处理视图结果---内部包含拦截器的最终处理(即不异常也要执行最终处理)
			processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
		}
		catch (Exception ex) {
            // 最终处理链
			triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
		}
		finally {
		    // ....
		}

   以下では、spring-mvcインターセプターチェーンとその他の関連クラスの簡単なシミュレーションを実装します。

1.シミュレーションの主なクラスの紹介

HandlerInterceptorインターセプター

    このインターフェースには3つのメソッドがあり、それぞれ、Handler要求の実行の前後に完了した処理を表します。
    
    リクエストの前処理:preHandle(リクエストリクエスト、レスポンスレスポンス、ハンドラーハンドラー)
    リクエストの後処理:postHandle(リクエストリクエスト、レスポンスレスポンス、ハンドラーハンドラー)
    リクエストの最終処理:afterCompletion(リクエストリクエスト、レスポンスレスポンス、ハンドラーハンドラー、例外exc)
        
HandlerExecutionChainインターセプターチェーン:
 
    関数の概要:
    インターセプターチェーンインスタンス内にList <HandlerInterceptor>変数があり、初期化中にインターセプターを追加するために使用され、intタイプのinterceptorIndex変数が使用されます。操作preHandle()メソッド、preメソッドにエラーがある場合、前操作を完了したインターセプターは、対応するafterCompletion最終処理操作を実行する必要があります。afterCompletion操作は、実行が完了したときに実行されるメソッドです。または実行エラーが発生します。
    
その他のクラス:
    ハンドラプロセッサ、元々はプロセッサアダプタを使用してリクエストを実行しました。簡略化するには、リクエストを固定的に処理するハンドラクラスとして設定します。
    リクエストリクエストクラス、msg pojo
    クラスに簡略化応答応答クラス、msgに簡略化pojoクラス

2.サンプルコード


public class MvcFilterDemo {
	
	/**模拟request*/
	static class Request {
		public Request(String msg) {
			super();
			this.msg = msg;
		}
		private String msg;
		public String getMsg() {
			return msg;
		}
		public void setMsg(String msg) {
			this.msg = msg;
		}
	}
	
	/**模拟response*/
	static class Response{
		private String msg;
		public String getMsg() {
			return msg;
		}
		public void setMsg(String msg) {
			this.msg = msg;
		}
	}
	
	/**处理接口*/
	static interface Handler {
		public Object invoke (Request request, Response response) ;
	}
	
	/** 拦截器接口*/
	static interface HandlerInterceptor {
		boolean preHandle(Request request, Response response, Handler handler);
		void postHandle(Request request, Response response, Handler handler);
		void afterCompletion(Request request, Response response, Exception exc);
	}
	
	/**
	 * 拦截器链
	 */
	static class HandlerExecutionChain {
		private Handler handler;
		private HandlerInterceptor[] interceptors; // 拦截链调用辅助用途
		private List<HandlerInterceptor> interceptorList = new ArrayList<HandlerInterceptor>(); // 装拦截器
		private int interceptorIndex = -1; // 前置执行的角标
		public HandlerExecutionChain(Handler handler) {
			this.handler = handler;
		}
		public Handler getHandler() {
			return this.handler;
		}
		public void addInterceptor(HandlerInterceptor interceptor) {
			this.interceptorList.add(interceptor);
		}
		public HandlerInterceptor[] getInterceptors() {
			if (this.interceptors == null && this.interceptorList != null) {
				this.interceptors = this.interceptorList.toArray(new HandlerInterceptor[this.interceptorList.size()]);
			}
			return this.interceptors == null ? new HandlerInterceptor[0] : this.interceptors;
		}
		
		// 1、前置执行所有 : 每次for循环,后记录已经执行的拦截器角标,并且如果拦截器返回false,此时的最后一个拦截器要执行下最终处理方法。
		boolean applyPreHandle(Request request, Response response) throws Exception {
			HandlerInterceptor[] interceptors = getInterceptors();
				for (int i = 0; i < interceptors.length; i++) {
					HandlerInterceptor interceptor = interceptors[i];
					if (!interceptor.preHandle(request, response, this.handler)) {
						triggerAfterCompletion(request, response, null);
						return false;
					}
					this.interceptorIndex = i;
				}
			return true;
		}
		
		// 2、后置执行所有:按反方向全部拦截器都执行。
		void applyPostHandle(Request request, Response response) throws Exception {
			HandlerInterceptor[] interceptors = getInterceptors();
			for (int i = interceptors.length - 1; i >= 0; i--) {
				HandlerInterceptor interceptor = interceptors[i];
				interceptor.postHandle(request, response, this.handler);
			}
		}
		
		// 3、最终执行:前置操作过不管是否中断请求还是出错,这个都会进行执行。
		void triggerAfterCompletion(Request request, Response response, Exception ex) throws Exception {
			HandlerInterceptor[] interceptors = getInterceptors();
			for (int i = this.interceptorIndex; i >= 0; i--) {
				HandlerInterceptor interceptor = interceptors[i];
				try {
					interceptor.afterCompletion(request, response, ex);
				} catch (Throwable ex2) {
				}
			}
		}
	
	}
	
	
	/**
	 * 请求调度总类
	 */
	static class DispatcherServlet{
		
		private HandlerExecutionChain chain ;

		public void setChain(HandlerExecutionChain chain) {
			this.chain = chain;
		}
		
		public void doService(Request request, Response response) throws Exception {
			Handler handler = chain.getHandler();
			try {
				// 前置拦截 --- 如果false,内部会
				if (!chain.applyPreHandle(request, response)) {
					return;
				}
				Exception dispatchException = null;
				try {
					handler.invoke(request, response);
					// 后置执行
					chain.applyPostHandle(request, response);
				} catch (Exception e) {
					dispatchException = e;
				}
				// 最终执行
				chain.triggerAfterCompletion(request, response, dispatchException);
			} catch (Exception e) {
				chain.triggerAfterCompletion(request, response, e);
			} finally {
				 // ....
			}
		}
	}
	
	测试阶段//
	
	public static class MyHandler implements Handler {
		@Override
		public Object invoke(Request request, Response response) {
			System.out.println("handler处理方法进行实际处理");
			String old = request.getMsg() ;
			request.setMsg(old + "[real excute]");
			return "hello wolrd";
		}
	}
	
	static class HandlerInterceptorOne implements HandlerInterceptor {
		@Override
		public boolean preHandle(Request request, Response response, Handler handler) {
			String old = request.getMsg() ;
			request.setMsg(old + "[one excute]");
			System.out.println("one 前置执行");
			return true;
		}
		@Override
		public void postHandle(Request request, Response response, Handler handler) {
			System.out.println("one 后置执行");
		}
		@Override
		public void afterCompletion(Request request, Response response, Exception exc) {
			System.out.println("one 最终执行");
		}
	}
	
	static class HandlerInterceptorTwo implements HandlerInterceptor {
		@Override
		public boolean preHandle(Request request, Response response, Handler handler) {
			String old = request.getMsg() ;
			request.setMsg(old + "[two excute]");
			System.out.println("two 前置执行");
			return true;
		}
		@Override
		public void postHandle(Request request, Response response, Handler handler) {
			System.out.println("two 后置执行");
		}
		@Override
		public void afterCompletion(Request request, Response response, Exception exc) {
			System.out.println("two 最终执行");
		}
	}
	
	
	/**
	 * 测试: 
	 */
	public static void main(String[] args) throws Exception {
		DispatcherServlet dispatcherServlet = new DispatcherServlet();
		MyHandler myHandler = new MyHandler();
		HandlerInterceptorOne oneInterceptor = new HandlerInterceptorOne();
		HandlerInterceptorTwo twoInterceptor = new HandlerInterceptorTwo();
		HandlerExecutionChain chain = new HandlerExecutionChain(myHandler);
		chain.addInterceptor(oneInterceptor);
		chain.addInterceptor(twoInterceptor);
		
		dispatcherServlet.setChain(chain);
		Request request = new Request("base request");
		Response response = new Response();
		dispatcherServlet.doService(request, response);
		System.out.println("最终结果" + request.getMsg());
//		one 前置执行
//		two 前置执行
//		handler处理方法进行实际处理
//		two 后置执行
//		one 后置执行
//		two 最终执行
//		one 最终执行
//		最终结果base request[one excute][two excute][real excute]
	}
	
}

コンプリート!

 

 

 

おすすめ

転載: blog.csdn.net/shuixiou1/article/details/112970999