El principio y ejemplo de demostración del interceptor spring-mvc

interceptor spring-mvc

   Visión general:

    El interceptor spring- mvc implementa principalmente la  interfaz HandlerInterceptor . Cuando el DispatcherServlet principal de spring-mvc ejecuta el método de solicitud de procesamiento principal doDispatch, el mapeador del procesador HandlerMapping encuentra el Handler correspondiente y envuelve la clase de implementación HandlerInterceptor de acuerdo con la ruta de solicitud del objeto de solicitud requset Ensamblar en HandlerInterceptorChain , y luego HandlerInterceptorChain llamará a los métodos específicos de cada interceptor de acuerdo con la secuencia de ejecución del Handler.

   El interceptor HandlerInterceptor procesa e intercepta principalmente la solicitud después del método de preprocesamiento y realiza el procesamiento después del método de posprocesamiento . Si se ejecuta el preprocesamiento de un determinado interceptor, el método de procesamiento final es el preprocesamiento solicitud de interrupción o el informe de error Se debe implementar el método de procesamiento final .

   Echemos un vistazo al código de ejecución principal simplificado doDispatch () de DispatcherServlet

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 {
		    // ....
		}

   A continuación, implementamos una simulación simple de una cadena de interceptores spring-mvc y otras clases relacionadas.

1. Introducción a las principales clases de simulación

Interceptor Interceptor Interceptor

    Esta interfaz tiene tres métodos, que representan respectivamente el procesamiento completo antes y después de la ejecución de la solicitud del controlador.
    
    Preprocesamiento de solicitudes: preHandle (Solicitud de solicitud, Respuesta de respuesta, Controlador de controlador)
    Solicitud de posprocesamiento: postHandle (Solicitud de solicitud, Respuesta de respuesta, Controlador de controlador)
    Solicitud de procesamiento final: afterCompletion (Solicitud de solicitud, Respuesta de respuesta, Controlador de controlador, Excepción exc)
        
HandlerExecutionChain interceptor chain:
 
    descripción general de la función:
    hay una variable List <HandlerInterceptor> dentro de la instancia de la cadena del interceptor, que se usa para agregar un interceptor durante la inicialización, y se usa una variable interceptorIndex de tipo int, que indica cuántos interceptores han realizado el pre operación El método preHandle (), si el pre-método tiene un error, el interceptor que ha completado la pre-operación necesita hacer la correspondiente operación de procesamiento final afterCompletion. La operación afterCompletion es el método que se ejecutará cuando se complete la ejecución o se produce el error de ejecución.
    
Otras clases:
    procesador de controlador, originalmente usaba el adaptador de procesador para ejecutar la solicitud. Para simplificarlo,
    configúrelo como una clase de controlador que maneja la solicitud de manera fija. Clase de solicitud de solicitud, simplificada en una clase de msg pojo Clase de
    respuesta de respuesta, simplificada en un mensaje clase pojo

2. Código de muestra


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]
	}
	
}

¡completo!

 

 

 

Supongo que te gusta

Origin blog.csdn.net/shuixiou1/article/details/112970999
Recomendado
Clasificación