资讯专栏INFORMATION COLUMN

SpringMVC总结

raledong / 2329人阅读

摘要:前端控制器根据返回的视图名,选择相应的视图进行渲染,并将模型数据传入到视图中以便展示。前端控制器将响应的结果返回给用户。

SpringMVC总结 一、spring MVC的工作内容

将URL映射到Java类或者方法

封装用户提交的数据

处理请求,调用相关的业务层,并封装响应的数据

将要响应的数据进行渲染

二、SpringMVC的优点和特点

与spring无缝集成(IOC、AOP)

约定优于配置

性能比Struts2好

设计中的角色或者职责划分明确

Restful

JUnit测试

异常处理

本地化、国际化

数据验证、类型转化等

拦截器

使用的人和公司比较多

简单、便捷、易学

springMVC处理请求的流程

springMVC基于请求驱动,所有设计都围绕一个中央servlet展开,它负责将请求分发给各个处理器(页面控制器、Controller),下图展示了springMVC处理请求的流程,图中的Front Controller(前端控制器)正是springMVC的DispatcherServlet;Controller称为处理器或应用控制器,由它来处理具体的请求,返回数据模型;View Template为具体视图,用于展示数据,响应请求.

具体处理请求步骤:

用户发送请求,被前端拦截器拦截,前端控制器根据请求的信息选择相应的页面控制器,并将请求委托给此页面控制器来处理。

页面控制器接收到请求后,首先收集并绑定请求参数到一个命令对象(表单对象)中,并进行验证转换等操作,然后将命令对象委托给业务对象处理,最后返回一个modelAndView对象。

前端控制器根据返回的视图名,选择相应的视图进行渲染,并将模型数据传入到视图中以便展示。

前端控制器将响应的结果返回给用户。

至此,整个请求流程结束,当然还有一些细节的问题,需要我们了解,比如:前端控制器如何选择页面控制器,前端控制器如果根据页面控制器的返回选择相应的视图进行渲染,等等。带着这些问题,我们将springMVC处理请求的流程图转换为架构图讨论一下。

先上一段代码:

 /**
     * Process the actual dispatching to the handler.
     * 

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. *

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 */ /** * 处理实际的请求分发到处理器. * 要获得具体的Handler, 需要先使用servlet的HandlerMappings. * 要获得HandlerAdpter, 需要先在servlet加载的各HandlerAdapter中查找, 找到第一个支持此Handler的Adapter. * 所有的HTTP方法都通过这个方法来处理的. 这个方法中, 由HandlerAdapter或Handler自己来决定哪些方法可以被调用. * @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; boolean multipartRequestParsed = false; WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request); try { ModelAndView mv = null; Exception dispatchException = null; try { // 检查请求是否为multipart(文件上传) processedRequest = checkMultipart(request); multipartRequestParsed = (processedRequest != request); // Determine handler for the current request. // 图中2,3两步, 通过HandlerMappsing映射, 获取处理请求的Handler mappedHandler = getHandler(processedRequest); if (mappedHandler == null || mappedHandler.getHandler() == null) { noHandlerFound(processedRequest, response); return; } // Determine handler adapter for the current request. // 图中步骤4, 将Handler包装成Adapter 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. // 图中5,6,7步骤, 由HandlerAdapter调用真正的处理器处理请求, 并返回ModelAndView对象 mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); if (asyncManager.isConcurrentHandlingStarted()) { return; } applyDefaultViewName(processedRequest, mv); // 后置拦截器 mappedHandler.applyPostHandle(processedRequest, response, mv); } catch (Exception ex) { dispatchException = ex; } // 图中8,9,10,11步骤, 处理Handler的处理结果, 这个结果可能是一个ModelAndView对象, 还可能是一个异常 // 第8,9步, 由viewResolver解析视图 // viewResolver.resolveViewName(viewName, locale) // 第10, 11步, 传入Model, 并渲染视图 // view.render(mv.getModelInternal(), request, response); 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); } } } }

步骤①, DispatcherServlet作为前端控制器, 统一的请求接收点, 控制全局的请求流程. 接收到用户请求, 自己不做处理, 而是将请求委托给其他的处理器进行处理.

步骤②③, DispatcherServlet通过HandlerMapping(处理映射器), 将请求映射为一个HandlerExecutionChain对象, 其中包括了页面控制器和对其配置的拦截器.

步骤④, DispatcherServlet通过获得的Handler(处理器, 页面控制器, Controller), 查找一个合适的HandlerAdapter(处理器适配器), 通过这个HandlerAdapter调用Handler实际处理请求的方法.

步骤⑤, 提取请求中的模型数据, 调用Handler实际处理请求的方法. 在调用方法时, 填充参数过程中, spring会根据配置做一些工作, 如: 数据转换, 数据格式化, 数据验证等.

步骤⑥⑦, Handler执行完成后, 将返回一个ModelAndView对象给DispatherServlet. ModelAndView对象中包含逻辑视图名或逻辑视图名和模型.

步骤⑧, 根据ModelAndView对象选择一个合适的ViewResolver(视图解析器).

步骤⑨, ViewResolver将ModelAndView中的逻辑视图名解释成View对象. ViewResolver也是接口, 同样采用了策略模式, 这样就很容易切换其他的视图类型.

步骤⑩⑪, 渲染视图时, 将Model数据传入视图中, 这里的Model数据是一个Map, 容易与各种视图类型相结合.

步骤⑫, 最后, 由DispatcherServlet将最终的响应结果返回给用户.

通过这些步骤, springmvc依赖几个对象共同完成了请求到响应的工作流程, 对于开发者来说, 这些对象是不可见的, 开发者只需要关心Handler处理器(页面控制器)中对请求的处理业务即可.

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/68036.html

相关文章

  • 慕课网_《SpringMVC拦截器》学习总结

    摘要:拦截器学习总结时间年月日星期六说明本文部分内容均来自慕课网。慕课网教学示例源码暂无。拦截器不依赖与容器,过滤器依赖与容器。拦截器只能对请求起作用,而过滤器则可以对几乎所有的请求起作用。共性问题在拦截器中处理,可以减少重复代码,便于维护。 《SpringMVC拦截器》学习总结 时间:2017年2月18日星期六说明:本文部分内容均来自慕课网。@慕课网:http://www.imooc.co...

    calx 评论0 收藏0
  • 慕课网_《SpringMVC起步》学习总结

    摘要:起步学习总结时间年月日星期四说明本文部分内容均来自慕课网。慕课网教学示例源码个人学习源码第一章简介起步课程简介简介基本概念项目搭建用进行开发课程总结前端控制器开发应用的通用架构方式。 《SpringMVC起步》学习总结 时间:2017年2月16日星期四说明:本文部分内容均来自慕课网。@慕课网:http://www.imooc.com教学示例源码:https://github.com/z...

    zombieda 评论0 收藏0
  • 慕课网_《SpringMVC数据绑定入门》学习总结

    摘要:数据绑定入门学习总结时间年月日星期日说明本文部分内容均来自慕课网。慕课网教学示例源码个人学习源码第一章课程介绍数据绑定入门概述数据绑定概念来自百度百科简单绑定是将一个用户界面元素控件的属性绑定到一个类型对象实例上的某个属性的方法。 《SpringMVC数据绑定入门》学习总结 时间:2017年2月19日星期日说明:本文部分内容均来自慕课网。@慕课网:http://www.imooc.co...

    Karrdy 评论0 收藏0
  • SpringMVC入门笔记

    摘要:入门笔记简介是一种基于的实现了设计模式的请求驱动类型的轻量级框架,是系开源项目中的一个,和配合使用。配置在中需要添加使用的和映射规则。入门较快,而掌握起来相对较难。 SpringMVC入门笔记 1. 简介 Spring MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架 ,是Spring系开源项目中的一个,和IoC配合使用。通过策略接口,Spring...

    zhaochunqi 评论0 收藏0
  • SpringMVC【校验器、统一处理异常、RESTful、拦截器】

    摘要:只要有一个拦截器不放行,不能执行完成号不放行和号不放行测试结果总结只有前边的拦截器方法放行,下边的拦截器的才执行。至于他们的拦截器链的调用顺序,和的是没有差别的。 前言 本博文主要讲解的知识点如下: 校验器 统一处理异常 RESTful 拦截器 Validation 在我们的Struts2中,我们是继承ActionSupport来实现校验的...它有两种方式来实现校验的功能 手写...

    marser 评论0 收藏0

发表评论

0条评论

raledong

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<