zoukankan      html  css  js  c++  java
  • Spring MVC之DispatcherServlet请求处理(二)

         回顾一下DispatcherServlet中doDispatch的处理流程

    /**
    	 * Process the actual dispatching to the handler.
    	 * <p>The handler will be obtained by applying the servlet's HandlerMappings in order.
    	 * The HandlerAdapter will be obtained by querying the servlet's installed HandlerAdapters
    	 * to find the first that supports the handler class.
    	 * <p>All HTTP methods are handled by this method. It's up to HandlerAdapters or handlers
    	 * themselves to decide which methods are acceptable.
    	 * @param request current HTTP request
    	 * @param response current HTTP response
    	 * @throws Exception in case of any kind of processing failure
    	 */
    	protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
    		HttpServletRequest processedRequest = request;
    		HandlerExecutionChain mappedHandler = null;
    		int interceptorIndex = -1;
    
    		try {
    			ModelAndView mv;
    			boolean errorView = false;
    
    			try {
    				// 判断请求是否是多媒体请求
    				processedRequest = checkMultipart(request);
    
    				// 获取当前请求的处理器HandlerExecutionChain
    				mappedHandler = getHandler(processedRequest, false);
    				if (mappedHandler == null || mappedHandler.getHandler() == null) {
    				//如果没有处理器,则返回一个404
    					noHandlerFound(processedRequest, response);
    					return;
    				}
    
    				// 获取当前请求的Handler适配器
    				HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
    
                    // Process last-modified header, if supported by the handler.
    				//获取当前请求的请求方法
    				String method = request.getMethod();
    				// 判断当前请求方法是否是GET请求
    				boolean isGet = "GET".equals(method);
    				// 如果是GET请求或者是HEAD
    				if (isGet || "HEAD".equals(method)) {
    					//获取最后修改时间
    					long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
    					if (logger.isDebugEnabled()) {
    						String requestUri = urlPathHelper.getRequestUri(request);
    						logger.debug("Last-Modified value for [" + requestUri + "] is: " + lastModified);
    					}
    					if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
    						return;
    					}
    				}
    
    				// 获取拦截器
    				HandlerInterceptor[] interceptors = mappedHandler.getInterceptors();
    				//如果拦截器不为空
    				if (interceptors != null) {
    					for (int i = 0; i < interceptors.length; i++) {
    						HandlerInterceptor interceptor = interceptors[i];
    						//如果处理请求被拦截,则结束请求,否则继续
    						if (!interceptor.preHandle(processedRequest, response, mappedHandler.getHandler())) {
    							triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null);
    							return;
    						}
    						interceptorIndex = i;
    					}
    				}
    
    				// 调用处理器获取一个视图
    				mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
    
    				//如果视图不为空,且有view,则设置默认视图名称
    				if (mv != null && !mv.hasView()) {
    					mv.setViewName(getDefaultViewName(request));
    				}
    
    				// Apply postHandle methods of registered interceptors.
    				if (interceptors != null) {
    					for (int i = interceptors.length - 1; i >= 0; i--) {
    						HandlerInterceptor interceptor = interceptors[i];
    						interceptor.postHandle(processedRequest, response, mappedHandler.getHandler(), mv);
    					}
    				}
    			}
    			catch (ModelAndViewDefiningException ex) {
    				logger.debug("ModelAndViewDefiningException encountered", ex);
    				mv = ex.getModelAndView();
    			}
    			catch (Exception ex) {
    				Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);
    				mv = processHandlerException(processedRequest, response, handler, ex);
    				errorView = (mv != null);
    			}
    
    			// 渲染视图
    			if (mv != null && !mv.wasCleared()) {
    				render(mv, processedRequest, response);
    				if (errorView) {
    					WebUtils.clearErrorRequestAttributes(request);
    				}
    			}
    			else {
    				if (logger.isDebugEnabled()) {
    					logger.debug("Null ModelAndView returned to DispatcherServlet with name '" + getServletName() +
    							"': assuming HandlerAdapter completed request handling");
    				}
    			}
    
    			// Trigger after-completion for successful outcome.
    			triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null);
    		}
    
    		catch (Exception ex) {
    			// Trigger after-completion for thrown exception.
    			triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex);
    			throw ex;
    		}
    		catch (Error err) {
    			ServletException ex = new NestedServletException("Handler processing failed", err);
    			// Trigger after-completion for thrown exception.
    			triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex);
    			throw ex;
    		}
    
    		finally {
    			// Clean up any resources used by a multipart request.
    			if (processedRequest != request) {
    				cleanupMultipart(processedRequest);
    			}
    		}
    	}

            可以发现对请求数据的处理是通过HandlerAdapter的handle()方法进行处理。下面将通过AnnotationMethodHandlerAdapter类来说明HandlerAdapter

    public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
    			throws Exception {
    		// 获取处理器的Class对象
    		Class<?> clazz = ClassUtils.getUserClass(handler);
    		Boolean annotatedWithSessionAttributes = this.sessionAnnotatedClassesCache.get(clazz);
    		if (annotatedWithSessionAttributes == null) {
    			// 如果有会话域的参数
    			annotatedWithSessionAttributes = (AnnotationUtils.findAnnotation(clazz, SessionAttributes.class) != null);
    			//将会话域的参数放入到缓存中
    			this.sessionAnnotatedClassesCache.put(clazz, annotatedWithSessionAttributes);
    		}
    		
    		if (annotatedWithSessionAttributes) {
    			// 总是防止缓存的情况下会话属性管理。
    			checkAndPrepare(request, response, this.cacheSecondsForSessionAttributeHandlers, true);
    			//  准备缓存防止会话域参数名称
    		}
    		else {
    			// Uses configured default cacheSeconds setting.
    			checkAndPrepare(request, response, true);
    		}
    
    		// 如果有必要可以在synchronized同步代码块中执行ivokeHandlerMethod方法,默认是false
    		if (this.synchronizeOnSession) {
    		    // 获取当前请求的session
    			HttpSession session = request.getSession(false);
    			if (session != null) {
    				//获取当前session的互斥锁对象
    				Object mutex = WebUtils.getSessionMutex(session);
    				//互斥调用处理器的方法
    				synchronized (mutex) {
    					return invokeHandlerMethod(request, response, handler);
    				}
    			}
    		}
    
    		return invokeHandlerMethod(request, response, handler);
    	}
    
    	protected ModelAndView invokeHandlerMethod(HttpServletRequest request, HttpServletResponse response, Object handler)
    			throws Exception {
    		// 获取指定处理器的ServeltHandlerMethodResovler对象
    		ServletHandlerMethodResolver methodResolver = getMethodResolver(handler);
    		// 获取请求的处理方法
    		Method handlerMethod = methodResolver.resolveHandlerMethod(request);
    		//
    		ServletHandlerMethodInvoker methodInvoker = new ServletHandlerMethodInvoker(methodResolver);
    		//构建一个ServletWebReqeust
    		ServletWebRequest webRequest = new ServletWebRequest(request, response);
    		ExtendedModelMap implicitModel = new BindingAwareModelMap();
    		//指定处理
    		Object result = methodInvoker.invokeHandlerMethod(handlerMethod, handler, webRequest, implicitModel);
    		// 获取处理后的ModleAndView
    		ModelAndView mav =
    				methodInvoker.getModelAndView(handlerMethod, handler.getClass(), result, implicitModel, webRequest);
    		methodInvoker.updateModelAttributes(handler, (mav != null ? mav.getModel() : null), implicitModel, webRequest);
    		// 返回ModelAndView对象
    		return mav;
    	}
    	/**
    	 * 对给定的处理器类型创建一个ServeltHandlerMethodResolver
    	 */
    	private ServletHandlerMethodResolver getMethodResolver(Object handler) {
    		// 获取用户定义的类
    		Class handlerClass = ClassUtils.getUserClass(handler);
    		// 从缓存中获取ServletHandlerMethodResolver
    		ServletHandlerMethodResolver resolver = this.methodResolverCache.get(handlerClass);
    		//如果缓存中不存在
    		if (resolver == null) {
    			synchronized (this.methodResolverCache) {
    				resolver = this.methodResolverCache.get(handlerClass);
    				if (resolver == null) {
    				   // 创建一个ServletHandlerMethodResolver对象并存入缓存
    					resolver = new ServletHandlerMethodResolver(handlerClass);
    					this.methodResolverCache.put(handlerClass, resolver);
    				}
    			}
    		}
    		return resolver;
    	}

        

  • 相关阅读:
    mvc edmx 的config文件
    Openwrt安装软件的方法
    如何用JQuery实现单元格 循环变背景色
    Vue的生命周期
    hmtl弹出框样式
    在星巴克买咖啡思考技术团队的管理
    RealTimePerformanceDemoView
    《SAAS创业指南》拆书笔记——产品打磨和商业模式初步验证
    基于日志的回放对比系统设计
    异常测试-中间件故障演练
  • 原文地址:https://www.cnblogs.com/wei-zw/p/8797777.html
Copyright © 2011-2022 走看看