springmvc 之DispatcherServlet逻辑处理

来源:互联网 发布:jquery.checktree.js 编辑:程序博客网 时间:2024/06/11 13:22

serlvet 根据http请求类型分别实现了doGet、doPost 、doPut、doDelete、doOptions、doTrace方法
我们经常使用的doGet doPost方法
处理流程
这里写图片描述

@Override    protected final void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        processRequest(request, response);    }    /**     * Delegate POST requests to {@link #processRequest}.     * @see #doService     */    @Override    protected final void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        processRequest(request, response);    }
protected final void processRequest(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        long startTime = System.currentTimeMillis();        Throwable failureCause = null;        LocaleContext previousLocaleContext = LocaleContextHolder.getLocaleContext();        LocaleContext localeContext = buildLocaleContext(request);        RequestAttributes previousAttributes = RequestContextHolder.getRequestAttributes();        ServletRequestAttributes requestAttributes = buildRequestAttributes(request, response, previousAttributes);        WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);        asyncManager.registerCallableInterceptor(FrameworkServlet.class.getName(), new RequestBindingInterceptor());        initContextHolders(request, localeContext, requestAttributes);        try {            doService(request, response);        }        catch (ServletException ex) {            failureCause = ex;            throw ex;        }        catch (IOException ex) {            failureCause = ex;            throw ex;        }        catch (Throwable ex) {            failureCause = ex;            throw new NestedServletException("Request processing failed", ex);        }        finally {            resetContextHolders(request, previousLocaleContext, previousAttributes);            if (requestAttributes != null) {                requestAttributes.requestCompleted();            }            if (logger.isDebugEnabled()) {                if (failureCause != null) {                    this.logger.debug("Could not complete request", failureCause);                }                else {                    if (asyncManager.isConcurrentHandlingStarted()) {                        logger.debug("Leaving response open for concurrent processing");                    }                    else {                        this.logger.debug("Successfully completed request");                    }                }            }            publishRequestHandledEvent(request, response, startTime, failureCause);        }    }

将localResolver和themeResovler等set到request属性中

@Override    protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {        if (logger.isDebugEnabled()) {            String resumed = WebAsyncUtils.getAsyncManager(request).hasConcurrentResult() ? " resumed" : "";            logger.debug("DispatcherServlet with name '" + getServletName() + "'" + resumed +                    " processing " + request.getMethod() + " request for [" + getRequestUri(request) + "]");        }        // 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)) {            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()) {                // Restore the original attribute snapshot, in case of an include.                if (attributesSnapshot != null) {                    restoreAttributesAfterInclude(request, attributesSnapshot);                }            }        }    }

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 {        //如果是MultipartContent类型的request则转换为MultipartHttpServletRequest  类型的request                processedRequest = checkMultipart(request);                multipartRequestParsed = (processedRequest != request);                // 根据request信息寻找对应的handler                mappedHandler = getHandler(processedRequest);                if (mappedHandler == null || mappedHandler.getHandler() == null) {                //如果没有找到对应的handler ,通过response反馈错误信息                    noHandlerFound(processedRequest, response);                    return;                }                // 根据当前handler找到对应的handlerAdapter                HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());                // 如果当前的handler支持last-mod                String method = request.getMethod();                boolean isGet = "GET".equals(method);                if (isGet || "HEAD".equals(method)) {                    long lastModified = ha.getLastModified(request, mappedHandler.getHandler());                    if (logger.isDebugEnabled()) {                        logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);                    }                    if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {                        return;                    }                }//拦截器prehandler方法的调用                if (!mappedHandler.applyPreHandle(processedRequest, response)) {                    return;                }                // 真正的激活handler并且返回视图                mv = ha.handle(processedRequest, response, mappedHandler.getHandler());                if (asyncManager.isConcurrentHandlingStarted()) {                    return;                }                //视图名称转换为应用于需要添加后缀名的情况                applyDefaultViewName(processedRequest, mv);                //应用所有拦截器postHandler方法                mappedHandler.applyPostHandle(processedRequest, response, mv);            }            catch (Exception ex) {                dispatchException = ex;            }            //hanlder实例返回view和exception的处理            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                if (mappedHandler != null) {                    mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);                }            }            else {                // Clean up any resources used by a multipart request.                if (multipartRequestParsed) {                    cleanupMultipart(processedRequest);                }            }        }    }
private void processDispatchResult(HttpServletRequest request, HttpServletResponse response,            HandlerExecutionChain mappedHandler, ModelAndView mv, Exception exception) throws Exception {        boolean errorView = false;        if (exception != null) {            if (exception instanceof ModelAndViewDefiningException) {                logger.debug("ModelAndViewDefiningException encountered", exception);                mv = ((ModelAndViewDefiningException) exception).getModelAndView();            }            else {                Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);                //将异常处理引导至HandlerExceptionResolver类的resolveException方法处理                mv = processHandlerException(request, response, handler, exception);                errorView = (mv != null);            }        }        // 如果在handler实例的处理返回了view,那么需要页面做处理        if (mv != null && !mv.wasCleared()) {            //处理页面跳转            render(mv, request, 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");            }        }        if (WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {            // Concurrent handling started during a forward            return;        }        if (mappedHandler != null) {            mappedHandler.triggerAfterCompletion(request, response, null);        }    }

通过遍历所有已注册的HandlerMapping来找到对应的handler,然后构建出一个HandlerExecutionChain,它包含了handler和HandlerMapping本身的一些拦截器

Spring3.1开始的版本,建议使用RequestMappingHandlerMapping和RequestMappingHandlerAdapter

protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {          for (HandlerMapping hm : this.handlerMappings) {              if (logger.isTraceEnabled()) {                  logger.trace(                          "Testing handler map [" + hm + "] in DispatcherServlet with name '" + getServletName() + "'");              }              HandlerExecutionChain handler = hm.getHandler(request);              if (handler != null) {                  return handler;              }          }          return null;      }  

其中HandlerMapping的getHandler实现:
这里的getHandlerInternal(request)是个抽象方法,由具体的HandlerMapping来实现,获取到的handler如果为空,则获取默认配置的handler,如果handler为String类型,则表示这个则会去Spring容器里面去找这样名字的bean。

public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {          Object handler = getHandlerInternal(request);          if (handler == null) {              handler = getDefaultHandler();          }          if (handler == null) {              return null;          }          // Bean name or resolved handler?          if (handler instanceof String) {              String handlerName = (String) handler;              handler = getApplicationContext().getBean(handlerName);          }          //HandlerExecutionChain 包含了一系列拦截器。会在调用Controller类对应方法之前、处理完方法还没返回视图、返回视图之后,这些动态加以拦截。        return getHandlerExecutionChain(handler, request);      }  

看一下RequestMappingHandlerMapping的getHandlerInternal方法实现

protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {        String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);        if (logger.isDebugEnabled()) {            logger.debug("Looking up handler method for path " + lookupPath);        }        this.mappingRegistry.acquireReadLock();        try {            HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);            if (logger.isDebugEnabled()) {                if (handlerMethod != null) {                    logger.debug("Returning handler method [" + handlerMethod + "]");                }                else {                    logger.debug("Did not find handler method for [" + lookupPath + "]");                }            }            return (handlerMethod != null ? handlerMethod.createWithResolvedBean() : null);        }        finally {            this.mappingRegistry.releaseReadLock();        }    }

根据http请求找对应的HandlerMethod

protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception {        List<Match> matches = new ArrayList<Match>();        List<T> directPathMatches = this.mappingRegistry.getMappingsByUrl(lookupPath);        if (directPathMatches != null) {            addMatchingMappings(directPathMatches, matches, request);        }        if (matches.isEmpty()) {            // No choice but to go through all mappings...            addMatchingMappings(this.mappingRegistry.getMappings().keySet(), matches, request);        }        if (!matches.isEmpty()) {            Comparator<Match> comparator = new MatchComparator(getMappingComparator(request));            Collections.sort(matches, comparator);            if (logger.isTraceEnabled()) {                logger.trace("Found " + matches.size() + " matching mapping(s) for [" +                        lookupPath + "] : " + matches);            }            Match bestMatch = matches.get(0);            if (matches.size() > 1) {                if (CorsUtils.isPreFlightRequest(request)) {                    return PREFLIGHT_AMBIGUOUS_MATCH;                }                Match secondBestMatch = matches.get(1);                if (comparator.compare(bestMatch, secondBestMatch) == 0) {                    Method m1 = bestMatch.handlerMethod.getMethod();                    Method m2 = secondBestMatch.handlerMethod.getMethod();                    throw new IllegalStateException("Ambiguous handler methods mapped for HTTP path '" +                            request.getRequestURL() + "': {" + m1 + ", " + m2 + "}");                }            }            handleMatch(bestMatch.mapping, lookupPath, request);            return bestMatch.handlerMethod;        }        else {            return handleNoMatch(this.mappingRegistry.getMappings().keySet(), lookupPath, request);        }    }

mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

@Override    public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)            throws Exception {        return handleInternal(request, response, (HandlerMethod) handler);    }

RequestMappingHandlerAdapter的handleInternal处理

@Override    protected ModelAndView handleInternal(HttpServletRequest request,            HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {        checkRequest(request);        if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {            applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers);        }        else {            prepareResponse(response);        }        // Execute invokeHandlerMethod in synchronized block if required.        if (this.synchronizeOnSession) {            HttpSession session = request.getSession(false);            if (session != null) {                Object mutex = WebUtils.getSessionMutex(session);                synchronized (mutex) {                    return invokeHandlerMethod(request, response, handlerMethod);                }            }        }        return invokeHandlerMethod(request, response, handlerMethod);    }

下一节 springmvc的@RequestMapping @Controller实现的

原创粉丝点击