当前位置: 首页 > news >正文

网站首页跳出弹窗google入口

网站首页跳出弹窗,google入口,媒体发稿平台,做网站找哪个部门之前在学servlet时写过JavaWeb与Asp.net工作原理比较分析,那篇主要是大致描述了下servlet的工作流程,今天在家了解了下springmvc的工作原理,与asp.net中的mvc进行了一下比较asp.net MVC 的处理流程,思想都是差不多,都是通过一个url怎么映射到…

 之前在学servlet时写过JavaWeb与Asp.net工作原理比较分析,那篇主要是大致描述了下servlet的工作流程,今天在家了解了下springmvc的工作原理,与asp.net中的mvc进行了一下比较asp.net MVC 的处理流程,思想都是差不多,都是通过一个url怎么映射到类中做完处理返回浏览器的过程,首先要解决三大问题,一是url映射转换成request和response对象的问题二是浏览器与服务端的数据交互问题三是服务端的request、response怎么响应给客户端。今天了解了下它的运行流畅,其实网上也有好多教程。

一图顶千言万语,用数据、用图说话,下图是springmvc的工作原理图。

SpringMVC工作流程

一、  用户发送请求至前端控制器DispatcherServlet。 

     1.DispatcherServlet它也是servlet,load-on-startup=1,tomcat启动时它也会初始化,初始化参数是contextConfigLocation上下文配置文件位置,参数值就是JavaWeb之Eclipse中使用Maven构建SpringMVC项目  配置的spring-mvc。在spring-mvc中可以配置自动扫描包名、默认注解映射支持、视图解释类、拦截器、对静态资源文件的访问等信息,通过自动扫描包名、注解映射支持、静态资源访问这些配置的信息在就会实例化HandlerMapping对象。这些对象是在tomcat进行参数初始化的时候也会实例化完成。在DispatcherServlet中维护着一个表,类似C#MVC中的RouteTable 路由表,存放的是HandlerMapping对象list.下面截图是DispatcherServlet中的部分代码,在DispatcherServlet中维护着handerMappings、handerAdapters等对象列表。在initStrategies中对上面的一些属性进行初始化。

    protected void initStrategies(ApplicationContext context) {initMultipartResolver(context);initLocaleResolver(context);initThemeResolver(context);initHandlerMappings(context);initHandlerAdapters(context);initHandlerExceptionResolvers(context);initRequestToViewNameTranslator(context);initViewResolvers(context);initFlashMapManager(context);}
View Code

  2.客户端发出请求,由 Tomcat 接收到这个请求,如果匹配 DispatcherServlet 在 web.xml 中配置的映射路径,Tomcat 就将请求转交给 DispatcherServlet 处理

二、  DispatcherServlet收到请求调用HandlerMapping处理器映射器。

  请求到达DispatcherServlet中之后,就是get、post这些请求,这些请求是DispatcherServlet的父类FrameworkServlet中定义着的,而在这些方法中又调用了processRequest,processRequest中调用了doService,DispatcherServlet重写了doService方法,doService中主要设置了一些属性和调用doDispatch方法,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);// Determine handler for the current request.mappedHandler = getHandler(processedRequest);if (mappedHandler == null) {noHandlerFound(processedRequest, response);return;}// Determine handler adapter for the current request.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()) {logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);}if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {return;}}if (!mappedHandler.applyPreHandle(processedRequest, response)) {return;}// Actually invoke the handler.mv = ha.handle(processedRequest, response, mappedHandler.getHandler());if (asyncManager.isConcurrentHandlingStarted()) {return;}applyDefaultViewName(processedRequest, mv);mappedHandler.applyPostHandle(processedRequest, response, mv);}catch (Exception ex) {dispatchException = ex;}catch (Throwable err) {// As of 4.3, we're processing Errors thrown from handler methods as well,// making them available for @ExceptionHandler methods and other scenarios.dispatchException = new NestedServletException("Handler dispatch failed", err);}processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);}catch (Exception ex) {triggerAfterCompletion(processedRequest, response, mappedHandler, ex);}catch (Throwable err) {triggerAfterCompletion(processedRequest, response, mappedHandler,new NestedServletException("Handler processing failed", err));}finally {if (asyncManager.isConcurrentHandlingStarted()) {// Instead of postHandle and afterCompletionif (mappedHandler != null) {mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);}}else {// Clean up any resources used by a multipart request.if (multipartRequestParsed) {cleanupMultipart(processedRequest);}}}}
View Code

上面的代码是核心代码,其实下面的几项其实就是代码的说明. 

processedRequest = checkMultipart(request);
multipartRequestParsed = (processedRequest != request);

上面这两句是判断请求是不是上传文件的请求

三、  处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。

mappedHandler = getHandler(processedRequest);
if (mappedHandler == null) {noHandlerFound(processedRequest, response);return;
}

getHander返回的是一个HandlerExecutionChain,这个HandlerExecutionChain中包含一个handler和多个HandlerInterceptor(拦截器),这个和asp.net中的管道模型有点类似,一个httphandler和多个httpmodule,httpmodule也是用来做拦截操作的。同时要留意HandlerExecutionChain是通过HandlerMapping对象的getHandler获取的.其实这里还可以扩展比如拦截器的使用、HandlerMapping的介绍等,由于篇幅有限,会在以后的博客中一个一个的介绍。

四、  DispatcherServlet调用HandlerAdapter处理器适配器。

HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
    protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {if (this.handlerAdapters != null) {for (HandlerAdapter ha : this.handlerAdapters) {if (logger.isTraceEnabled()) {logger.trace("Testing handler adapter [" + ha + "]");}if (ha.supports(handler)) {return ha;}}}throw new ServletException("No adapter for handler [" + handler +"]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");}
View Code

获取适配器是通过遍历handlerAdapters列表找的,HandlerAdapter包含了3个方法.boolean supports(Object handler);ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;long getLastModified(HttpServletRequest request, Object handler);

/** Copyright 2002-2013 the original author or authors.** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at**      http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/package org.springframework.web.servlet;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import org.springframework.lang.Nullable;/*** MVC framework SPI, allowing parameterization of the core MVC workflow.** <p>Interface that must be implemented for each handler type to handle a request.* This interface is used to allow the {@link DispatcherServlet} to be indefinitely* extensible. The {@code DispatcherServlet} accesses all installed handlers through* this interface, meaning that it does not contain code specific to any handler type.** <p>Note that a handler can be of type {@code Object}. This is to enable* handlers from other frameworks to be integrated with this framework without* custom coding, as well as to allow for annotation-driven handler objects that* do not obey any specific Java interface.** <p>This interface is not intended for application developers. It is available* to handlers who want to develop their own web workflow.** <p>Note: {@code HandlerAdapter} implementors may implement the {@link* org.springframework.core.Ordered} interface to be able to specify a sorting* order (and thus a priority) for getting applied by the {@code DispatcherServlet}.* Non-Ordered instances get treated as lowest priority.** @author Rod Johnson* @author Juergen Hoeller* @see org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter* @see org.springframework.web.servlet.handler.SimpleServletHandlerAdapter*/
public interface HandlerAdapter {/*** Given a handler instance, return whether or not this {@code HandlerAdapter}* can support it. Typical HandlerAdapters will base the decision on the handler* type. HandlerAdapters will usually only support one handler type each.* <p>A typical implementation:* <p>{@code* return (handler instanceof MyHandler);* }* @param handler handler object to check* @return whether or not this object can use the given handler*/boolean supports(Object handler);/*** Use the given handler to handle this request.* The workflow that is required may vary widely.* @param request current HTTP request* @param response current HTTP response* @param handler handler to use. This object must have previously been passed* to the {@code supports} method of this interface, which must have* returned {@code true}.* @throws Exception in case of errors* @return ModelAndView object with the name of the view and the required* model data, or {@code null} if the request has been handled directly*/@NullableModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;/*** Same contract as for HttpServlet's {@code getLastModified} method.* Can simply return -1 if there's no support in the handler class.* @param request current HTTP request* @param handler handler to use* @return the lastModified value for the given handler* @see javax.servlet.http.HttpServlet#getLastModified* @see org.springframework.web.servlet.mvc.LastModified#getLastModified*/long getLastModified(HttpServletRequest request, Object handler);}
View Code

五、  HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)。

六、  Controller执行完成返回ModelAndView。

七、  HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet。

                // 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()) {logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);}if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {return;}}if (!mappedHandler.applyPreHandle(processedRequest, response)) {return;}// Actually invoke the handler.mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
View Code

 上面的几行代码先判断如果是get请求更新下lastModified请求头,然后执行HandlerExecutionChain中的applyPreHandle这个方法.

    boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {HandlerInterceptor[] interceptors = getInterceptors();if (!ObjectUtils.isEmpty(interceptors)) {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;}
View Code
    void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, @Nullable Exception ex)throws Exception {HandlerInterceptor[] interceptors = getInterceptors();if (!ObjectUtils.isEmpty(interceptors)) {for (int i = this.interceptorIndex; i >= 0; i--) {HandlerInterceptor interceptor = interceptors[i];try {interceptor.afterCompletion(request, response, this.handler, ex);}catch (Throwable ex2) {logger.error("HandlerInterceptor.afterCompletion threw exception", ex2);}}}}
View Code

在applyPreHandle中它会遍历该HandlerExecutionChain中所有的拦截器,然后使用拦截器通过preHandle对handler进行预处理,如果所有的拦截器都能处理那就会继续往下执行,如果一旦有一个拦截器不能处理,就没必要往下走了,那就会触发triggerAfterCompletion方法,在triggerAfterCompletion中它是倒序遍历的拦截器的,执行完triggerAfterCompletion返回false之后doDispatch这个方法就执行结束了,下面的八、九、十、十一就不再执行。从第五步括号里的备注也能猜出来HandlerExecutionChain.handler是什么,它可以是Controller。

八、  DispatcherServlet将ModelAndView传给ViewReslover视图解析器。

 九、  ViewReslover解析后返回具体View。

applyDefaultViewName(processedRequest, mv);
    private void applyDefaultViewName(HttpServletRequest request, @Nullable ModelAndView mv) throws Exception {if (mv != null && !mv.hasView()) {String defaultViewName = getDefaultViewName(request);if (defaultViewName != null) {mv.setViewName(defaultViewName);}}}
View Code
    protected String getDefaultViewName(HttpServletRequest request) throws Exception {return (this.viewNameTranslator != null ? this.viewNameTranslator.getViewName(request) : null);}
View Code

找到ModelAndView对应的viewname,设置成它的属性值。

mappedHandler.applyPostHandle(processedRequest, response, mv);

applyPostHandle与applyPreHandle是对应着的,遍历handler的拦截器,执行postHandle方法。

十、DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。

processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
    private void processDispatchResult(HttpServletRequest request, HttpServletResponse response,@Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv,@Nullable 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);mv = processHandlerException(request, response, handler, exception);errorView = (mv != null);}}// Did the handler return a view to render?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 forwardreturn;}if (mappedHandler != null) {mappedHandler.triggerAfterCompletion(request, response, null);}}
View Code
    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 != null ? this.localeResolver.resolveLocale(request) : request.getLocale());response.setLocale(locale);View view;String viewName = mv.getViewName();if (viewName != null) {// We need to resolve the view name.view = resolveViewName(viewName, 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() + "'");}try {if (mv.getStatus() != null) {response.setStatus(mv.getStatus().value());}view.render(mv.getModelInternal(), request, response);}catch (Exception ex) {if (logger.isDebugEnabled()) {logger.debug("Error rendering view [" + view + "] in DispatcherServlet with name '" +getServletName() + "'", ex);}throw ex;}}
View Code

在processDispatchResult方法中有一句render(mv, request, response),在render中先是获取View对象然后调用view.render(mv.getModelInternal(), request, response);将view和model绑定来进行渲染试图。

十一、 DispatcherServlet响应用户。

响应用户其实是在父类FrameworkServlet的processRequest方法中

十二、小结

上面黑字部分是参考其他博客的,红色的是通过读源码找的,现在基本清楚springmvc大致的流程,其实如果继续深入的话,还有好多知识点,这篇博客就写到这,以后再慢慢补充。好久没熬夜学习了,今天算是毕业之后最用功的一天了,哈哈...(今天四月一,愚人节!!!)

参考:https://www.cnblogs.com/xiaoxi/p/6164383.html

 

http://www.lbrq.cn/news/2634103.html

相关文章:

  • 淘宝客网站开发服务商怎么提交百度收录
  • 电子商务80gb的流量网站够用吗百度地图网页版
  • 天权网站建设优化设计七年级上册语文答案
  • 重庆政府网站建设磁力猫torrent kitty
  • 自己做代购网站公司建设网站哪家好
  • 福田网站建设设计百度热搜榜排行
  • 金融网站建设内容小程序推广引流
  • 哪个网站做图文素材多唐山百度提升优化
  • 外贸网站建设网网站一般需要怎么推广
  • 推广展示类网站营销渠道有哪些
  • 游戏网站开发需求分析网络营销的定义
  • 深圳电商网站建设线上销售水果营销方案
  • wordpress 获取根目录南京seo网络推广
  • 泰安网站建设如何百度站长平台登录
  • 重新建网站需要转域名吗推广app赚钱的平台
  • 做淘宝客网站推广被骗网络营销是以什么为中心
  • 大连华南网站制作公司游戏优化大师手机版
  • 建设厅官方网站响应式模版移动优化
  • 动态网站建设试卷推广产品的渠道
  • 手机原理网站百度推广费用预算表
  • 网站建设的步骤教程视频域名备案查询站长工具
  • 宜城网站建设哪家好网站如何推广运营
  • 微网站是什么时候创建的慧生活798app下载
  • 芜湖做网站哪家好seo优化总结
  • 做网站的技术难点网络推广的公司更可靠
  • 重庆建设机电网站好看的网站ui
  • 网站建设常用软件jas怎么做网站推广多少钱
  • 网站怎么做高权重最佳搜索引擎磁力王
  • 国家车辆保险网站推广普通话手抄报
  • 做欧美贸易的主要有哪些网站公司网站如何建设
  • 计算机毕业设计java疫情开放下的新冠信息共享平台 基于Java的社区疫情防控人员流动管理系统 疫情防控期间社区人员动态管理系统
  • day28-NFS
  • 网站IP被劫持?三步自建防护盾
  • 【模电笔记】—— 直流稳压电源——稳压电路
  • Boosting 知识点整理:调参技巧、可解释性工具与实战案例
  • yolov1-v3原理解析