O princípio e a demonstração de exemplo do interceptor spring-mvc

interceptor spring-mvc

   Visão geral:

    O interceptor spring-mvc implementa principalmente a  interface HandlerInterceptor . Quando o DispatcherServlet central de spring-mvc executa o método de solicitação de processamento principal doDispatch, o mapeador de processador HandlerMapping encontra o Handler correspondente e envolve a classe de implementação HandlerInterceptor de acordo com o caminho de solicitação do objeto de solicitação requset Assemble em um HandlerInterceptorChain , e então o HandlerInterceptorChain irá chamar os métodos específicos de cada interceptor de acordo com a seqüência de execução do Handler.

   O interceptor HandlerInterceptor processa e intercepta principalmente a solicitação após o método de pré-processamento e realiza o processamento após o método de pós-processamento . Se o pré-processamento de um determinado interceptor é executado, então o método de processamento final é o pré-processamento solicitação de interrupção ou relatório de erro. O método de processamento final deve ser implementado.

   Vamos dar uma olhada no código de execução 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 {
		    // ....
		}

   Abaixo, implementamos uma simulação simples de uma cadeia de interceptores spring-mvc e outras classes relacionadas.

1. Introdução às principais aulas de simulação

Interceptor HandlerInterceptor

    Essa interface possui três métodos, que representam respectivamente o processamento concluído antes e depois da execução da solicitação do Handler.
    
    Solicitação de pré-processamento: preHandle (solicitação de solicitação, resposta de resposta, manipulador de manipulador)
    Pós-processamento de solicitação: postHandle (solicitação de solicitação, resposta de resposta, manipulador de manipulador)
    Solicitação de processamento final: afterCompletion (solicitação de solicitação, resposta de resposta, manipulador de manipulador, exceção exc)
        
Cadeia do interceptor HandlerExecutionChain:
 
    visão geral da função:
    há uma variável List <HandlerInterceptor> dentro da instância da cadeia do interceptor, que é usada para adicionar um interceptor durante a inicialização, e uma variável do tipo int interceptorIndex é usada, que indica quantos interceptores realizaram o pré- operação O método preHandle (), se o pré-método tiver um erro, o interceptor que completou a pré-operação precisa fazer a operação de processamento final afterCompletion correspondente. A operação afterCompletion é o método que será executado quando a execução for concluída ou ocorre o erro de execução.
    
Outras classes:
    Processador Handler, originalmente usado o adaptador do processador para executar a solicitação. Para simplificá-lo, defina-o como uma classe Handler que lida com a solicitação de maneira fixa.
    Classe de solicitação de solicitação, simplificada em uma classe msg pojo. Classe de
    resposta de resposta, simplificada em uma msg aula de pojo

2. Código de amostra


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!

 

 

 

Acho que você gosta

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