前言:
今天小伙伴们对“mvc获取url的组件是什么”大约比较关怀,你们都想要剖析一些“mvc获取url的组件是什么”的相关知识。那么小编也在网络上搜集了一些关于“mvc获取url的组件是什么””的相关知识,希望我们能喜欢,小伙伴们快快来学习一下吧!简介
SpringMVC的核心都是围绕着前端调度器-DispatcherServlet设计的,DispatcherServlet负责请求统一的调度,实际的工作交给相应的组件执行,各司其职,如下图:
组件DispatcherServlet
DispatcherServlet-前端调度器 负责拦截前端的请求 然后分发到各个处理器的方法中
HandlerMapping
处理器映射器负责通过请求的url 匹配 对应的执行器链。
HandlerAdapter
处理器适配器,负责执行处理器的具体方法,返回ModelAndView
ModelAndView
封装视图和数据
ViewReslover
解析ModelAndView 返回view
现在大部分项目都是前后端分离以JSON的方式进行数据交互,所以后面我们重点讲解DispatcherServlet、HandlerMapping、HandlerAdapter 这三个组件。
源码
dispatcherServlet 是Servlet的一个实现类吗,所以在请求进来时会进入到Servlet#Service方法,然后根据类图 一顿分析 可以得出 请求会进入到 DispatcherServlet#doService方法
doService
入口函数:org.springframework.web.servlet#doService
@Overrideprotected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception { logRequest(request); .....省略代码 try { // 调度逻辑找到了 继续跟 doDispatch(request, response); } .....省略代码}doDispatch
请求调度开始:org.springframework.web.servlet#doDispatch
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { ..... 代码省略 HandlerExecutionChain mappedHandler = null; try { ModelAndView mv = null; Exception dispatchException = null; try { // 检查是否为文件上传 processedRequest = checkMultipart(request); multipartRequestParsed = (processedRequest != request); // 根据reaquest 获取处理器链 // HandlerExecutionChain 对象 除了处理器handler 还包含拦截器等其他信息 mappedHandler = getHandler(processedRequest); if (mappedHandler == null) { // url没有对应的处理器 返回404 noHandlerFound 此处简单逻辑大家自己跟一下就好了 noHandlerFound(processedRequest, response); return; } // 根据处理器获取到处理器适配器 为后面执行处理器准备 HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); ..... 代码省略 // 执行处理器链 中 拦截器的 preHandle 方法 if (!mappedHandler.applyPreHandle(processedRequest, response)) { // false直接返回 return; } // 处理器适配器执行具体的 处理器方法 返回 ModelAndView mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); if (asyncManager.isConcurrentHandlingStarted()) { return; } // 设置viewName applyDefaultViewName(processedRequest, mv); // 执行处理器链 中 拦截器的 postHandle 方法 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); } // 5.解析并渲染视图ModelAndView 正常执行拦截器afterCompletion 方法 processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException); } catch (Exception ex) { // 异常执行拦截器afterCompletion 方法 triggerAfterCompletion(processedRequest, response, mappedHandler, ex); } catch (Throwable err) { // 异常执行拦截器afterCompletion 方法 triggerAfterCompletion(processedRequest, response, mappedHandler, new NestedServletException("Handler processing failed", err)); } ..... 代码省略 }processDispatchResult
渲染视图:org.springframework.web.servlet#processDispatchResult
private void processDispatchResult(HttpServletRequest request, HttpServletResponse response, @Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv, @Nullable Exception exception) throws Exception { .....省略代码 if (mv != null && !mv.wasCleared()) { // 渲染视图 render(mv, request, response); if (errorView) { WebUtils.clearErrorRequestAttributes(request); } } .....省略代码 if (mappedHandler != null) { // 执行拦截器 afterCompletion 方法 mappedHandler.triggerAfterCompletion(request, response, null); }}protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception { ... View view; String viewName = mv.getViewName(); if (viewName != null) { // 此处会获取 视图解析器 viewResolvers 解析视图 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() + "'"); } } ... 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 + "]", ex); } throw ex; }}总结
本文将SpringMVC 整体的一个请求流程粗略的过了一遍,主要分下面几个步骤
DispatcherServlet#doDispatch: 前端控制器开始调度请求流程.getHandler(processedRequest): 根据request 获取处理器 mappedHandler( HandlerExecutionChain 对象包括拦截器)getHandlerAdapter(mappedHandler.getHandler()): 根据处理器获取处理器适配器 hamappedHandler.applyPreHandle(): 执行mappedHandler中拦截器的preHandle 方法ha.handle(): 处理器适配器 执行 处理器方法 返回视图mappedHandler.applyPostHandle() 执行mappedHandler中拦截器的postHandle 方法processDispatchResult():解析视图然后进行视图渲染 返回给客户端
标签: #mvc获取url的组件是什么