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