springmvc
2021-12-05 21:14:26 34 举报
AI智能生成
Spring MVC是一个基于Java的实现了MVC设计模式的请求驱动类型的轻量级Web框架,通过一套注解,快速简单的实现了请求驱动模型。Spring MVC提供了一个松耦合和分层的结构,使应用程序的开发更加简单、灵活。它是Spring框架的一部分,可以与Spring框架中的其他模块无缝集成,如数据访问层(Spring Data JPA)、事务管理(Spring Transaction)等。Spring MVC具有强大的视图处理能力,支持多种视图技术,如JSP、Freemarker、Thymeleaf等。同时,它还提供了丰富的验证、国际化、拦截器等特性,使得开发过程更加便捷高效。
作者其他创作
大纲/内容
基础应用
简介
三层架构mvc
三层架构mvc <br>注意这里的springmvc 中的m 是视图和控制器传递的model,并不是持久层的m,所以整个springmvc也就是表现层。
Spring MVC 是什么
为了解决表现层问题 的web框架,它们都是基于 MVC 设计模<br>式的。⽽这些表现层框架的主要职责就是处理前端HTTP请求。<br>Spring MVC 本质可以认为是对servlet的封装,简化了我们serlvet的开发<br>作⽤:1)接收请求 2)返回响应,跳转⻚⾯<br>
⼯作流程
开发流程
<ol><li>配置DispatcherServlet前端控制器<br></li><li>开发处理具体业务逻辑的Handler(@Controller、@RequestMapping)<br></li><li>xml配置⽂件配置controller扫描,配置springmvc三⼤件<br></li><li>将xml⽂件路径告诉springmvc(DispatcherServlet)</li></ol>
请求处理流程
第⼀步:⽤户发送请求⾄前端控制器DispatcherServlet<br><br>第⼆步:DispatcherServlet收到请求调⽤HandlerMapping处理器映射器<br><br>第三步:处理器映射器根据请求Url找到具体的Handler(后端控制器),⽣成处理器对象及处理器拦截器(如果 有则⽣成)⼀并返回DispatcherServlet<br><br>第四步:DispatcherServlet调⽤HandlerAdapter处理器适配器去调⽤Handler<br><br>第五步:处理器适配器执⾏Handler<br><br>第六步:Handler执⾏完成给处理器适配器返回ModelAndView<br><br>第七步:处理器适配器向前端控制器返回 ModelAndView,ModelAndView 是SpringMVC 框架的⼀个底层对 象,包括 Model 和 View<br><br>第⼋步:前端控制器请求视图解析器去进⾏视图解析,根据逻辑视图名来解析真正的视图。<br><br>第九步:视图解析器向前端控制器返回View<br><br>第⼗步:前端控制器进⾏视图渲染,就是将模型数据(在 ModelAndView 对象中)填充到 request 域<br><br>第⼗⼀步:前端控制器向⽤户响应结果
Spring MVC 九⼤组件
HandlerMapping(处理器映射器)<br>
HandlerMapping 的作⽤便是找到请求相应的处理器Handler 和 Interceptor.
HandlerAdapter(处理器适配器)
HandlerAdapter 是⼀个适配器,Spring MVC 中 Handler 可以是任意形式的,只要能处理请<br>求即可。但是把请求交给 Servlet 的时候,由于 Servlet 的⽅法结构都是<br>doService(HttpServletRequest req,HttpServletResponse resp)形式的,要让固定的 Servlet 处理<br>⽅法调⽤ Handler 来进⾏处理。
HandlerExceptionResolver(在handler处理中异常拦截)
HandlerExceptionResolver ⽤于处理 Handler 产⽣的异常情况。它的作⽤是根据异常设置<br>ModelAndView,之后交给渲染⽅法进⾏渲染,渲染⽅法会将 ModelAndView 渲染成⻚⾯。
ViewResolver (视图解析器)
只有⼀个resolveViewName()⽅法。Controller层返回的String类型视图名<br>viewName 最终会在这⾥被解析成为View<br>主要完成2件事:1. 找到渲染所⽤的模板 2. 填⼊参数
RequestToViewNameTranslator(从请求中获取 ViewName)
ViewResolver 根据ViewName 查找 View,但有的 Handler 处理完成之后,没有设置 View,也没有设置 ViewName,<br>便要通过这个组件从请求中查找 ViewName。
LocaleResolver(从请求中解析出 Locale)
ViewResolver 组件的 resolveViewName ⽅法需要两个参数,⼀个是视图名,⼀个是 Locale。<br>LocaleResolver ⽤于从请求中解析出 Locale,⽐如中国 Locale 是 zh-CN,⽤来表示⼀个区域。
ThemeResolver(解析主题)
Spring MVC 中⼀套主题对应⼀个 properties⽂件,⾥⾯存放着与当前主题相关的所有资源,如图<br>⽚、CSS样式等。创建主题⾮常简单,只需准备好资源,然后新建⼀个“主题名.properties”并将资<br>源设置进去,放在classpath下,之后便可以在⻚⾯中使⽤了
MultipartResolver(解析请求中的文件)
MultipartResolver 的作⽤就<br>是封装普通的请求,使其拥有⽂件上传的功能。
FlashMapManager(重定向时的参数传递)
在处理⽤户订单时候,为了避免重复提交,可以处理完<br>post请求之后重定向到⼀个get请求,这个get请求可以⽤来显示订单详情之类的信息。这样做虽然<br>可以规避⽤户重新提交订单的问题,通过FlashMap来传递。在显示订单信息的⻚⾯<br>上就可以直接从Model中获取数据。FlashMapManager 就是⽤来管理 FalshMap 的
请求参数绑定
SpringMVC框架对Servlet的封装,简化了servlet的很多操作
默认⽀持 Servlet API 作为⽅法参数<br>
例如HttpServletRequest、HttpServletResponse、HttpSession 原生servlet
绑定简单类型参数
简单数据类型:<br>⼋种基本数据类型及其包装类型<br>参数类型推荐使⽤包装数据类型,因为基础数据类型不可以为null<br><br>整型:Integer、int<br><br>字符串:String<br><br>单精度:Float、float<br><br>双精度:Double、double<br><br>布尔型:Boolean、boolean<br><br>说明:对于布尔类型的参数,请求的参数值为true或false。或者1或0<br><br>注意:绑定简单数据类型参数,只需要直接声明形参即可<br>(形参参数名和传递的参数名要保持⼀<br>致,建议 使⽤包装类型,当形参参数名和传递参数名不⼀致时可以使⽤@RequestParam注解进⾏<br>⼿动映射)->handle03(@RequestParam("ids") Integer id)<br>
绑定Pojo类型参数
接收pojo类型参数,直接形参声明即可,类型就是Pojo的类型,形参名⽆所谓<br>* 但是要求传递的参数名必须和Pojo的属性名保持⼀致->handle04(User user)
绑定Pojo包装对象参数
一个pojo嵌套另一个pojo<br>url:/demo/handle05?user.id=1&user.username=zhangsan
绑定⽇期类型参数(需要配置⾃定义类型转换器)
前端:/demo/handle06?birthday=2019-10-08"<br>后端:handle06(Date birthday)<br>自定义转换器:DateConverter implements Converter<String, Date><br>注册⾃定义类型转换器:见备注<br>
对 Restful ⻛格请求⽀持
Restful 介绍
例子:/account/1 HTTP GET :得到 id = 1 的 account<br> /account/1 HTTP DELETE:删除 id = 1 的 account<br> /account/1 HTTP PUT:更新 id = 1 的 account<br>定义:互联⽹所有的事物都是资源<br>操作:使⽤HTTP请求中的method⽅法put、delete、post、get来操作资源
Spring MVC ⽀持 RESTful ⻛格请求,具体讲的就是使⽤ <font color="#c41230">@PathVariable 注解</font>获取 RESTful ⻛格的请求URL中的路径变量<br>例子 :<br>@RequestMapping(value = "/handle/{id}",method =<br>{RequestMethod.GET})<br>handleGet(@PathVariable("id") Integer id)
web.xml中配置请求⽅式过滤器。配置见备注
Ajax Json交互
使⽤注解@RequstBody
@responseBody注解的作⽤是将controller的⽅法返回的对象通过适当的转换器转换为指定的格式之<br>后,写⼊到response对象的body区<br><font face="楷体" color="#c41230"><b>注意:在使⽤此注解之后不会再⾛视图处理器,⽽是直接将数据写⼊到输⼊流中,他的效果等同于通过response对象输出指定<br>格式的数据。</b></font>
springmvc需要jar包,见备注
⾼级技术
拦截器(Inteceptor)
监听器、过滤器和拦截器对⽐
Servlet:处理Request请求和Response响应
<b>过滤器(Filter)</b>:<br>对Request请求起到过滤的作⽤,作⽤在Servlet之前,如果配置为/*可以对所<br>有的资源访问(servlet、js/css<font color="#c41230">静态资源等)进⾏过滤处理</font>
<b>监听器(Listener)</b>:<br><font color="#c41230">随Web应⽤的启动⽽启动,只初始化⼀次,然后会⼀直运⾏监视,随Web应⽤的停⽌⽽销毁</font><br><br>作⽤⼀:做⼀些初始化⼯作,web应⽤中<font color="#c41230"><b>spring容器启动</b></font>ContextLoaderListener<br>作⽤⼆:监听web中的特定事件,⽐如<b><font color="#c41230">HttpSession,ServletRequest的创建和销毁</font></b>;变量的创建、<br>销毁和修改等。可以<b><font color="#c41230">在某些动作前后增加处理,实现监控,⽐如统计在线⼈数,利⽤<br>HttpSessionLisener</font></b>等。<br>
<b>拦截器(Interceptor)</b>:<br>是SpringMVC、Struts等表现层框架⾃⼰的,不会拦截<br>jsp/html/css/image的访问等,只会<b><font color="#c41230">拦截访问的控制器⽅法</font></b>(Handler)。<br><br>serlvet、filter、listener是配置在web.xml中的,⽽interceptor是<br><font color="#c41230">配置在表现层框架⾃⼰的配置⽂件中</font>的<br>在Handler业务逻辑执⾏之前拦截⼀次<br>在Handler逻辑执⾏完毕但未跳转⻚⾯之前拦截⼀次<br>在跳转⻚⾯之后拦截⼀次<br>
拦截器的执⾏流程
1)程序先执⾏preHandle()⽅法,如果该⽅法的返回值为true,则程序会继续向下执⾏处理器中的⽅<br>法,否则将不再向下执⾏。<br>2)在业务处理器(即控制器Controller类)处理完请求后,会执⾏postHandle()⽅法,然后会通过<br>DispatcherServlet向客户端返回响应。<br>3)在DispatcherServlet处理完请求后,才会执⾏afterCompletion()⽅法。
多个拦截器的执⾏流程
当有多个拦截器同时⼯作时,它们的preHandle()⽅法会按照配置⽂件中拦截器的配置<br>顺序执⾏,⽽它们的postHandle()⽅法和afterCompletion()⽅法则会按照配置顺序的反序执⾏。
处理multipart形式的数据
jar包 & 配置⽂件上传解析器 见备注
handler 见备注
在控制器中处理异常
@ControllerAdvice 捕捉所有异常
基于Flash属性的跨重定向请求数据传递
转发:A 找 B 借钱400,B没有钱但是悄悄的找到C借了400块钱给A ,<b> <font color="#c41230">url不会变,参数也不会丢失,⼀个请求</font></b><br>重定向:A 找 B 借钱400,B 说我没有钱,你找别⼈借去,那么A ⼜带着400块的借钱需求找到<br>C,<b style=""><font color="#c41230">两个请求</font><br><font color="#000000">例子:</font><font color="#c41230"> </font></b>redirectAttributes.addFlashAttribute("name",name);// 设置参数<br>return "redirect:handle01";
⼿写 MVC 框架
流程
具体见手写代码
源码深度剖析
前端控制器 DispatcherServlet 继承结构
处理请求的流程
1)调⽤getHandler()获取到能够处理当前请求的执⾏链 HandlerExecutionChain(Handler+拦截<br>器)<br>但是如何去getHandler的?后⾯进⾏分析<br>2)调⽤getHandlerAdapter();获取能够执⾏1)中Handler的适配器<br>但是如何去getHandlerAdapter的?后⾯进⾏分析<br>3)适配器调⽤Handler执⾏ha.handle(总会返回⼀个ModelAndView对象)<br>4)调⽤processDispatchResult()⽅法完成视图渲染跳转
getHandler⽅法剖析
遍历两个HandlerMapping,试图获取能够处理当前请求的执⾏链
getHandlerAdapter⽅法剖析
遍历各个HandlerAdapter,看哪个Adapter⽀持处理当前Handler
ha.handle⽅法剖析
doInvoke 结合参数 代理调用handler
processDispatchResult⽅法剖析
<ol><li>render⽅法完成渲染</li><li>视图解析器解析出View视图对象</li><li>在解析出View视图对象的过程中会判断是否重定向、是否转发等,不同的情况封装的是不同的View实现</li><li>解析出View视图对象的过程中,要将逻辑视图名解析为物理视图名</li><li>封装View视图对象之后,调⽤了view对象的render⽅法</li><li>渲染数据</li><li>把modelMap中的数据暴露到request域中,这也是为什么后台model.add之后在jsp中可以从请求</li><li>域取出来的根本原因</li><li>将数据设置到请求域中</li></ol>
SpringMVC九⼤组件初始化
在DispatcherServlet中定义了九个属性,每⼀个属性都对应⼀种组件
九⼤组件的初始化时机<br>
initStrategies⽅法
initHandlerMappings(context)<br>如果按照类型和按照固定id从ioc容器中找不到对应组件,则会按照默认策略进⾏注册初始化,默<br>认策略在DispatcherServlet.properties⽂件中配置<br>
注意:多部件解析器的初始化必须按照id注册对象(multipartResolver)
SSM 整合
整合策略(Spring + Mybatis)+ SpringMVC
Mybatis整合Spring
<b>整合⽬标</b><br><br><ul><li><font color="#c41230">数据库连接池以及事务管理都交给Spring容器来完成</font></li><li><font color="#c41230">SqlSessionFactory对象应该放到Spring容器中作为单例对象管理</font></li><li><font color="#c41230">Mapper动态代理对象交给Spring管理,我们从Spring容器中直接获得Mapper的代理对象</font><br><br></li></ul><b>整合所需 Jar 分析</b><br><br><ul><li>Junit测试jar(4.12版本)</li><li>Mybatis的jar(3.4.5)</li><li>Spring相关jar(spring-context、spring-test、spring-jdbc、spring-tx、spring-aop、aspectjweaver)</li><li>Mybatis/Spring整合包jar(mybatis-spring-xx.jar)</li><li>Mysql数据库驱动jar</li><li><span style="font-size: inherit;">Druid数据库连接池的jar</span></li></ul><br style="font-size: inherit;"><span style="font-size: inherit;"><b>Pom坐标见备注</b></span><br>
整合SpringMVC
引⼊pom坐标
扫描controller
web.xml 配置 contextConfigLocation(加载配置文件)、listener(spring框架启动)、servlet(配置dispatch,加载springmvc.xml、过滤规则)
注意:mvc优先 加载 springmvc.xml applicationContext.xml,扫包要分开
附录
乱码问题解决
Post请求乱码,web.xml中加⼊过滤器
Get请求乱码(Get请求乱码需要修改tomcat下server.xml的配置)<br><Connector URIEncoding="utf-8" connectionTimeout="20000" port="8080"<br>protocol="HTTP/1.1" redirectPort="8443"/><br>
Spring MVC 必备设计模式
策略模式
ViewResolver->render()
模板⽅法模式 AbstractApplicationContext->refresh()->postProcessBeanFactory 交给子类实现
适配器模式 HandlerAdapter 在 doDispatch() ⽅法中调⽤了 getHandlerAdapter() ⽅法 选出最合适的适配器
0 条评论
下一页