zoukankan      html  css  js  c++  java
  • springMVC框架

    一、springMVC原理

    如图:

     

      ①、发起请求到前端控制器(DispatcherServlet)

      ②、前端控制器请求HandlerMapping查找 Handler

               可以根据xml配置、注解进行查找

      ③、处理器映射器HandlerMapping向前端控制器返回Handler

      ④、前端控制器调用处理器适配器去执行Handler

      ⑤、处理器适配器去执行Handler

      ⑥、Handler执行完成给适配器返回ModelAndView

      ⑦、处理器适配器向前端控制器返回ModelAndView

               ModelAndView是springmvc框架的一个底层对象,包括 Model和view

      ⑧、前端控制器请求视图解析器去进行视图解析

               根据逻辑视图名解析成真正的视图(jsp)

      ⑨、视图解析器向通过ModelAndView对象的数据获取View对象

      ⑩、视图对象返回给视图解析器

      11、视图解析器通过视图对象将ModelAndView填充到request域,返回给前端控制器

      12、前端控制器向用户响应结果

    查看源代码

    @Override
        protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
    
            if (logger.isDebugEnabled()) {
                String requestUri = urlPathHelper.getRequestUri(request);
                String resumed = WebAsyncUtils.getAsyncManager(request).hasConcurrentResult() ? " resumed" : "";
                logger.debug("DispatcherServlet with name '" + getServletName() + "'" + resumed +
                        " processing " + request.getMethod() + " request for [" + requestUri + "]");
            }
    
            // Keep a snapshot of the request attributes in case of an include,
            // to be able to restore the original attributes after the include.
            Map<String, Object> attributesSnapshot = null;
            if (WebUtils.isIncludeRequest(request)) {
                logger.debug("Taking snapshot of request attributes before include");
                attributesSnapshot = new HashMap<String, Object>();
                Enumeration<?> attrNames = request.getAttributeNames();
                while (attrNames.hasMoreElements()) {
                    String attrName = (String) attrNames.nextElement();
                    if (this.cleanupAfterInclude || attrName.startsWith("org.springframework.web.servlet")) {
                        attributesSnapshot.put(attrName, request.getAttribute(attrName));
                    }
                }
            }
    
            // Make framework objects available to handlers and view objects.
            request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, getWebApplicationContext());
            request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver);
            request.setAttribute(THEME_RESOLVER_ATTRIBUTE, this.themeResolver);
            request.setAttribute(THEME_SOURCE_ATTRIBUTE, getThemeSource());
    
            FlashMap inputFlashMap = this.flashMapManager.retrieveAndUpdate(request, response);
            if (inputFlashMap != null) {
                request.setAttribute(INPUT_FLASH_MAP_ATTRIBUTE, Collections.unmodifiableMap(inputFlashMap));
            }
            request.setAttribute(OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap());
            request.setAttribute(FLASH_MAP_MANAGER_ATTRIBUTE, this.flashMapManager);
    
            try {
                doDispatch(request, response);
            }
            finally {
                if (WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {
                    return;
                }
                // Restore the original attribute snapshot, in case of an include.
                if (attributesSnapshot != null) {
                    restoreAttributesAfterInclude(request, attributesSnapshot);
                }
            }
        }

    以上代码request对象的出来,doDispatch方法作用相当于处理分发

    protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
            HttpServletRequest processedRequest = request;
            HandlerExecutionChain mappedHandler = null;
            boolean multipartRequestParsed = false;
    
            WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
    
            try {
                ModelAndView mv = null;
                Exception dispatchException = null;
    
                try {
                    processedRequest = checkMultipart(request);
                    multipartRequestParsed = processedRequest != request;
    
                    // 确定当前请求的处理程序。
                    mappedHandler = getHandler(processedRequest, false);
                    if (mappedHandler == null || mappedHandler.getHandler() == null) {
                        noHandlerFound(processedRequest, response);
                        return;
                    }
    
                    // 确定当前请求的处理程序适配器。1、获取handler,2、获取HandlerAdapter
                    HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
    
                    // Process last-modified header, if supported by the handler.
                    String method = request.getMethod();
                    boolean isGet = "GET".equals(method);
                    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;
                        }
                    }
    
                    if (!mappedHandler.applyPreHandle(processedRequest, response)) {
                        return;
                    }
    
                    try {
                        // 实际调用处理程序。上面流程中的⑥
                        mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
                    }
                    finally {
                        if (asyncManager.isConcurrentHandlingStarted()) {
                            return;
                        }
                    }
              //这个是View的处理,具体怎么做的没深入了解
                    applyDefaultViewName(request, mv);
                    mappedHandler.applyPostHandle(processedRequest, response, mv);
                }
                catch (Exception ex) {
                    dispatchException = ex;
                }
                processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
            }
            catch (Exception ex) {
                triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
            }
            catch (Error err) {
                triggerAfterCompletionWithError(processedRequest, response, mappedHandler, err);
            }
            finally {
                if (asyncManager.isConcurrentHandlingStarted()) {
                    // Instead of postHandle and afterCompletion
                    mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
                    return;
                }
                // Clean up any resources used by a multipart request.
                if (multipartRequestParsed) {
                    cleanupMultipart(processedRequest);
                }
            }
        }

     视图解析

    protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {
            // Determine locale for request and apply it to the response.
            Locale locale = this.localeResolver.resolveLocale(request);
            response.setLocale(locale);
    
            View view;
            if (mv.isReference()) {
                // 根据视图名称获得视图对象
                view = resolveViewName(mv.getViewName(), mv.getModelInternal(), locale, request);
                if (view == null) {
                    throw new ServletException(
                            "Could not resolve view with name '" + mv.getViewName() + "' in servlet with name '" +
                                    getServletName() + "'");
                }
            }
            else {
                // No need to lookup: the ModelAndView object contains the actual View object.
                view = mv.getView();
                if (view == null) {
                    throw new ServletException("ModelAndView [" + mv + "] neither contains a view name nor a " +
                            "View object in servlet with name '" + getServletName() + "'");
                }
            }
    
            // Delegate to the View object for rendering.
            if (logger.isDebugEnabled()) {
                logger.debug("Rendering view [" + view + "] in DispatcherServlet with name '" + getServletName() + "'");
            }
            view.render(mv.getModelInternal(), request, response);
        }

    视图渲染:实际上就是将模型数据封装到HttpServletRequest对象中(request域)

    protected void exposeModelAsRequestAttributes(Map<String, Object> model, HttpServletRequest request) throws Exception {
            for (Map.Entry<String, Object> entry : model.entrySet()) {
                String modelName = entry.getKey();
                Object modelValue = entry.getValue();
                if (modelValue != null) {
                    request.setAttribute(modelName, modelValue);
                    if (logger.isDebugEnabled()) {
                        logger.debug("Added model object '" + modelName + "' of type [" + modelValue.getClass().getName() +
                                "] to request in view with name '" + getBeanName() + "'");
                    }
                }
                else {
                    request.removeAttribute(modelName);
                    if (logger.isDebugEnabled()) {
                        logger.debug("Removed model object '" + modelName +
                                "' from request in view with name '" + getBeanName() + "'");
                    }
                }
            }
  • 相关阅读:
    HDFS数据流——读数据流程
    HDFS网络拓扑概念及机架感知(副本节点选择)
    HDFS数据流——写数据流程
    HDFS基本概念
    Hadoop运行模式:本地模式、伪分布模式、完全分布模式
    Java枚举enum关键字
    Java内部类
    Eclipse常用快捷键
    Linux中Mysql安装卸载
    服务器同时运行两个项目
  • 原文地址:https://www.cnblogs.com/WarBlog/p/15002241.html
Copyright © 2011-2022 走看看