當前位置:
首頁 >
前端技术
> javascript
>内容正文
javascript
Spring MVC之DispatcherServlet请求处理(二)
生活随笔
收集整理的這篇文章主要介紹了
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);// 獲取當前請求的處理器HandlerExecutionChainmappedHandler = getHandler(processedRequest, false);if (mappedHandler == null || mappedHandler.getHandler() == null) {//如果沒有處理器,則返回一個404noHandlerFound(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請求或者是HEADif (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方法,默認是falseif (this.synchronizeOnSession) {// 獲取當前請求的sessionHttpSession 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);//構建一個ServletWebReqeustServletWebRequest webRequest = new ServletWebRequest(request, response);ExtendedModelMap implicitModel = new BindingAwareModelMap();//指定處理Object result = methodInvoker.invokeHandlerMethod(handlerMethod, handler, webRequest, implicitModel);// 獲取處理后的ModleAndViewModelAndView 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);// 從緩存中獲取ServletHandlerMethodResolverServletHandlerMethodResolver 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;}?
?
????
?
轉載于:https://www.cnblogs.com/wei-zw/p/8797777.html
總結
以上是生活随笔為你收集整理的Spring MVC之DispatcherServlet请求处理(二)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [裴礼文数学分析中的典型问题与方法习题参
- 下一篇: 01 排版