文章来自 https://my.oschina.net/u/3080373/blog/1438733

spring mvc简介与运行原理

Spring的模型-视图-控制器(MVC)框架是围绕一个DispatcherServlet来设计的,这个Servlet会把请求分发给各个处理器,并支持可配置的处理器映射、视图渲染、本地化、时区与主题渲染等,甚至还能支持文件上传。

  • (1) Http请求:客户端请求提交到DispatcherServlet。
  • (2) 寻找处理器:由DispatcherServlet控制器查询一个或多个HandlerMapping,找到处理请求的Controller。
  • (3) 调用处理器:DispatcherServlet将请求提交到Controller。
  • (4)(5)调用业务处理和返回结果:Controller调用业务逻辑处理后,返回ModelAndView。
  • (6)(7)处理视图映射并返回模型: DispatcherServlet查询一个或多个ViewResoler视图解析器,找到ModelAndView指定的视图。
  • (8) Http响应:视图负责将结果显示到客户端。

主要注解

ContextLoaderListener

在讲ContextLoaderListener之前,首先来了解一下web.xml的作用。

  • 一个web中可以没有web.xml文件,也就是说,web.xml文件并不是web工程必须的。web.xml文件是用来初始化配置信息:比如Welcome页面、servlet、servlet-mapping、filter、listener、启动加载级别等。当你的web工程没用到这些时,你可以不用web.xml文件来配置你的Application。
  • 当要启动某个web项目时,服务器软件或容器如(tomcat)会第一步加载项目中的web.xml文件,通过其中的各种配置来启动项目,只有其中配置的各项均无误时,项目才能正确启动。web.xml有多项标签,在其加载的过程中顺序依次为:context-param >> listener >> fileter >> servlet。(同类多个节点以出现顺序依次加载)

而spring mvc启动过程大致分为两个过程:

  • ContextLoaderListener初始化,实例化IoC容器,并将此容器实例注册到ServletContext中。
  • DispatcherServlet初始化。

其中ContextLoaderListener监听器它实现了ServletContextListener这个接口,在web.xml配置这个监听器,启动容器时,就会默认执行它实现的方法。在ContextLoaderListener中关联了ContextLoader这个类,所以整个加载配置过程由ContextLoader来完成。

  • ContextLoaderListener在web.xml中的配置
<!-- 配置contextConfigLocation初始化参数 -->
<context-param><param-name>contextConfigLocation</param-name><param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param><!-- 配置ContextLoaderListerner -->
<listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

ServletContextListener 接口有两个方法:contextInitialized,contextDestroyed

DispatcherServlet

Spring MVC框架,与其他很多web的MVC框架一样:请求驱动;所有设计都围绕着一个中央Servlet来展开,它负责把所有请求分发到控制器;同时提供其他web应用开发所需要的功能。不过Spring的中央处理器,DispatcherServlet,能做的比这更多。

下图展示了Spring Web MVC的DispatcherServlet处理请求的工作流。熟悉设计模式的朋友会发现,DispatcherServlet应用的其实就是一个“前端控制器”的设计模式(其他很多优秀的web框架也都使用了这个设计模式)。

  • 流程图

  • 在web.xml中的配置
<!-- servlet定义 -->
<servlet><servlet-name>dispatcher</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><load-on-startup>1</load-on-startup>
</servlet><servlet-mapping><servlet-name>dispatcher</servlet-name><url-pattern>/</url-pattern>
</servlet-mapping>

其中

  • load-on-startup:表示启动容器时初始化该Servlet;
  • url-pattern:表示哪些请求交给Spring Web MVC处理, “/” 是用来定义默认servlet映射的。也可以如“*.html”表示拦截所有以html为扩展名的请求。

在Spring MVC中,每个DispatcherServlet都持有一个自己的上下文对象WebApplicationContext,它又继承了根(root)WebApplicationContext对象中已经定义的所有bean。这些继承的bean可以在具体的Servlet实例中被重载,在每个Servlet实例中你也可以定义其scope下的新bean。

WebApplicationContext继承自ApplicationContext,它提供了一些web应用经常需要用到的特性。它与普通的ApplicationContext不同的地方在于,它支持主题的解析,并且知道它关联到的是哪个servlet(它持有一个该ServletContext的引用)

spring mvc同时提供了很多特殊的注解,用于处理请求和渲染视图等。DispatcherServlet初始化的过程中会默认使用这些特殊bean进行配置。如果你想指定使用哪个特定的bean,你可以在web应用上下文WebApplicationContext中简单地配置它们。

其中,常用的ViewResolver的配置。以jsp作为视图为例

<!-- 对模型视图名称的解析,即在模型视图名称添加前后缀 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix" value="/WEB-INF/jsp/" /><property name="suffix" value=".jsp" />
</bean>

配置上传文件限制MultipartResolver

<!-- 上传限制 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"><!-- 上传文件大小限制为31M,31*1024*1024 --><property name="maxUploadSize" value="32505856"/>
</bean>

applicationContext.xml中的标签

文件上传

前面说到DispatcherServlet中有个特殊的Bean叫MultipartResolver,可用于限制文件的上传大小等。当解析器MultipartResolver完成处理时,请求便会像其他请求一样被正常流程处理。

  • 表单
<form method="post" action="/form" enctype="multipart/form-data"><input type="text" name="name"/><input type="file" name="file"/><input type="submit"/>
</form>
  • 控制器
@RequestMapping(path = "/form", method = RequestMethod.POST)public String handleFormUpload(@RequestParam("name") String name, @RequestParam("file") MultipartFile file) {if (!file.isEmpty()) {byte[] bytes = file.getBytes();// store the bytes somewherereturn "redirect:uploadSuccess";}return "redirect:uploadFailure";
}

异常处理

先来说下常见的异常处理有几种方式,如下图:

Spring的处理器异常解析器HandlerExceptionResolver接口的实现负责处理各类控制器执行过程中出现的异常。也是上面提到的,是DispatcherServlet中的特殊bean,可以自定义配置处理。

某种程度上讲,HandlerExceptionResolver与你在web应用描述符web.xml文件中能定义的异常映射(exception mapping)很相像,不过它比后者提供了更灵活的方式。比如它能提供异常被抛出时正在执行的是哪个处理器这样的信息。

  • HandlerExceptionResolver 提供resolveException接口
public interface HandlerExceptionResolver {  ModelAndView resolveException(  HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex);
}
  • 在BaseController中使用 @ExceptionHandler注解处理异常
    @ExceptionHandler(Exception.class)public Object exceptionHandler(Exception ex, HttpServletResponse response, HttpServletRequest request) throws IOException {String url = "";String msg = ex.getMessage();Object resultModel = null;try {if (ex.getClass() == HttpRequestMethodNotSupportedException.class) {url = "admin/common/500";System.out.println("--------毛有找到对应方法---------");} else if (ex.getClass() == ParameterException.class) {//自定义的异常} else if (ex.getClass() == UnauthorizedException.class) {url = "admin/common/unauth";System.out.println("--------毛有权限---------");}String header = req.getHeader("X-Requested-With");boolean isAjax = "XMLHttpRequest".equalsIgnoreCase(header);String method = req.getMethod();boolean isPost = "POST".equalsIgnoreCase(method);if (isAjax || isPost) {return Message.error(msg);} else {ModelAndView view = new ModelAndView(url);view.addObject("error", msg);view.addObject("class", ex.getClass());view.addObject("method", request.getRequestURI());return view;}} catch (Exception exception) {logger.error(exception.getMessage(), exception);return resultModel;} finally {logger.error(msg, ex);ex.printStackTrace();}}
  • 在web.xml中处理异常
<!-- 默认的错误处理页面 -->
<error-page><error-code>403</error-code><location>/403.html</location>
</error-page>
<error-page><error-code>404</error-code><location>/404.html</location>
</error-page>
<!-- 仅仅在调试的时候注视掉,在正式部署的时候不能注释 -->
<!-- 这样配置也是可以的,表示发生500错误的时候,转到500.jsp页面处理。 -->
<error-page> <error-code>500</error-code> <location>/500.html</location>
</error-page> <!-- 这样的配置表示如果jsp页面或者servlet发生java.lang.Exception类型(当然包含子类)的异常就会转到500.jsp页面处理。 -->
<error-page> <exception-type>java.lang.Exception</exception-type> <location>/500.jsp</location>
</error-page> <error-page> <exception-type>java.lang.Throwable</exception-type> <location>/500.jsp</location>
</error-page><!-- 当error-code和exception-type都配置时,exception-type配置的页面优先级高及出现500错误,发生异常Exception时会跳转到500.jsp-->
  • 来一个问题:HandlerExceptionResolver和web.xml中配置的error-page会有冲突吗?

解答:如果resolveException返回了ModelAndView,会优先根据返回值中的页面来显示。不过,resolveException可以返回null,此时则展示web.xml中的error-page的500状态码配置的页面。 当web.xml中有相应的error-page配置,则可以在实现resolveException方法时返回null。 API文档中对返回值的解释: return a corresponding ModelAndView to forward to, or null for default processing.

Spring-MVC 思维导图相关推荐

  1. spring框架思维导图,简约概括

    spring框架思维导图,简约概括 Spring之旅 简化java开发 激发pojo的潜能 依赖注入 应用切面 使用模版消除样板式代码 容纳你的bean 与应用上下文共事 bean的生命周期 俯翰Sp ...

  2. spring体系思维导图

    spring体系思维导图 1. spring 思维导图 2. springboot 思维导图 3. springcloud 思维导图 之前整理的,后续持续更新中 1. spring 思维导图 2. s ...

  3. Spring框架思维导图

  4. Spring全家桶及思维导图

    目录 前言 Spring Framework的思维导图 Spring MVC的思维导图 Spring Boot的思维导图 Spring Cloud的思维导图 总结 前言 spring系列的框架作为老牌 ...

  5. Spring思维导图,让spring不再难懂(一)

    转载自 Spring思维导图,让spring不再难懂(一) 摘要: Spring是一个开源框架,是为了解决企业应用程序开发复杂性而创建的.框架的主要优势之一就是其分层架构,分层架构允许您选择使用哪一个 ...

  6. Spring思维导图(MVC篇)

    写在前面 生活就像海洋,只有意志坚强的人才能到达彼岸. 已经很久没有发文章了呀,想必大家都挂念我了,哈哈. 温故而知新,今天一起来复习一下spring mvc的内容吧. spring mvc简介与运行 ...

  7. Spring思维导图,让Spring不再难懂(mvc篇)

    转载自 Spring思维导图,让Spring不再难懂(mvc篇) spring mvc简介与运行原理 Spring的模型-视图-控制器(MVC)框架是围绕一个DispatcherServlet来设计的 ...

  8. Spring思维导图,让Spring不再难懂(aop篇)

    2019独角兽企业重金招聘Python工程师标准>>> 什么是aop AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Or ...

  9. 2023最新首发,全网最全 Spring Boot 学习宝典(附思维导图)

    作者:bug菌 博客:CSDN.掘金.infoQ.51CTO等 简介:CSDN/阿里云/华为云/51CTO博客专家,博客之星Top30,掘金年度人气作者Top40,51CTO年度博主Top12,掘金/ ...

  10. 敖丙思维导图-Spring

    敖丙思维导图系列目录 这些知识整理都是自己查阅帅丙资料(当然还有其他渠道)加以总结滴~ 每周都会更新知识进去. 如有不全或错误还请大家在评论中指出~ 敖丙思维导图-集合 敖丙思维导图-多线程之sync ...

最新文章

  1. 有了这个科研思路,高水平SCI就在手边!
  2. 计算机二级find,Excel函数-find、if和iferror-计算机二级Office
  3. Spring-AOP @AspectJ切点函数之@annotation()
  4. wordpress 显示数学公式 (MathJax-LaTeX)
  5. 无光驱不支持USB设备启动的笔记本,如何使用Ghost来安装系统
  6. HTML5: 两个viewport的故事(第二部分)
  7. c语言利用fun求最小值,c语言:请编写函数fun(),他的功能是:求f(0)到f(50)的最小值,已知:f(0)=f(1)=1,f(2)=0,f...
  8. python程序双向链表_Python 实现双向链表(图解)
  9. java多线程-线程停止
  10. 终于把W32.Spybot.Worm给消灭了(这个标题不能用了)
  11. Atitit 知识与数据 信息 加工方法总结 目录 1.1. 信息加工是指通过判别、筛选、分类、排序、分析和研究等一系列过程 1 1.2. 首先通过聚类信息 专题化 分组聚合 1 1.3. 多种聚
  12. charset参数 sqluldr2_sqluldr2 oracle直接导出数据为文本的小工具使用
  13. 74HC595芯片级联的测试万能代码
  14. 数值分析(9):数值积分之Newton-Cotes求积公式和复合求积公式
  15. 你不知道的几个牛逼网站,欢迎收藏
  16. GDIplus的初次接触--加载并显示常用格式图片
  17. C++解决《无重复字符的最长子串》问题(滑动窗口(unordered_set),string)
  18. BFC(Block Formatting Context) 及其如何工作
  19. 区间选点(贪心,区间问题)
  20. 思科模拟器 --- 三层交换机实现VLAN间路由

热门文章

  1. 杠杆炒股从三步学会正确的做t方法
  2. latex 表格添加注释
  3. 计算机网络相关论文翻译(1)A Brief Overview of the NEBULA Future Internet Architecture
  4. java查询elasticsearch_elasticsearch查询所有数据restful api以及java代码实现
  5. Volly 框架简介
  6. the 95th-percentile ,50th,99th等
  7. 【钢琴人狂喜】如何利用AI一键转MIDI并编辑,最后用特效钢琴完美演绎出来?(Giant MIDI-Piano+Domino汉化版1.43+Embers特效钢琴)
  8. GUID分区与MBR分区
  9. 蓝牙防丢器实现安卓的BLE接口编程
  10. 【第74期】安全工程师最详细学习和职业规划路线(书籍推荐和导图下载)