springmvc
2021-12-05 21:14:26 28 举报
AI智能生成
登录查看完整内容
Spring MVC是一个基于Java的实现了MVC设计模式的请求驱动类型的轻量级Web框架,通过一套注解,快速简单的实现了请求驱动模型。Spring MVC提供了一个松耦合和分层的结构,使应用程序的开发更加简单、灵活。它是Spring框架的一部分,可以与Spring框架中的其他模块无缝集成,如数据访问层(Spring Data JPA)、事务管理(Spring Transaction)等。Spring MVC具有强大的视图处理能力,支持多种视图技术,如JSP、Freemarker、Thymeleaf等。同时,它还提供了丰富的验证、国际化、拦截器等特性,使得开发过程更加便捷高效。
作者其他创作
大纲/内容
springmvc
基础应用
简介
三层架构mvc
三层架构mvc 注意这里的springmvc 中的m 是视图和控制器传递的model,并不是持久层的m,所以整个springmvc也就是表现层。
Spring MVC 是什么
为了解决表现层问题 的web框架,它们都是基于 MVC 设计模式的。⽽这些表现层框架的主要职责就是处理前端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 域第⼗⼀步:前端控制器向⽤户响应结果
Spring MVC 九⼤组件
HandlerMapping(处理器映射器)
HandlerMapping 的作⽤便是找到请求相应的处理器Handler 和 Interceptor.
HandlerAdapter(处理器适配器)
HandlerExceptionResolver(在handler处理中异常拦截)
HandlerExceptionResolver ⽤于处理 Handler 产⽣的异常情况。它的作⽤是根据异常设置ModelAndView,之后交给渲染⽅法进⾏渲染,渲染⽅法会将 ModelAndView 渲染成⻚⾯。
ViewResolver (视图解析器)
只有⼀个resolveViewName()⽅法。Controller层返回的String类型视图名viewName 最终会在这⾥被解析成为View主要完成2件事:1. 找到渲染所⽤的模板 2. 填⼊参数
RequestToViewNameTranslator(从请求中获取 ViewName)
LocaleResolver(从请求中解析出 Locale)
ViewResolver 组件的 resolveViewName ⽅法需要两个参数,⼀个是视图名,⼀个是 Locale。LocaleResolver ⽤于从请求中解析出 Locale,⽐如中国 Locale 是 zh-CN,⽤来表示⼀个区域。
ThemeResolver(解析主题)
Spring MVC 中⼀套主题对应⼀个 properties⽂件,⾥⾯存放着与当前主题相关的所有资源,如图⽚、CSS样式等。创建主题⾮常简单,只需准备好资源,然后新建⼀个“主题名.properties”并将资源设置进去,放在classpath下,之后便可以在⻚⾯中使⽤了
MultipartResolver(解析请求中的文件)
MultipartResolver 的作⽤就是封装普通的请求,使其拥有⽂件上传的功能。
FlashMapManager(重定向时的参数传递)
在处理⽤户订单时候,为了避免重复提交,可以处理完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)
绑定Pojo类型参数
接收pojo类型参数,直接形参声明即可,类型就是Pojo的类型,形参名⽆所谓* 但是要求传递的参数名必须和Pojo的属性名保持⼀致->handle04(User user)
绑定Pojo包装对象参数
一个pojo嵌套另一个pojourl:/demo/handle05?user.id=1&user.username=zhangsan
绑定⽇期类型参数(需要配置⾃定义类型转换器)
前端:/demo/handle06?birthday=2019-10-08\
对 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来操作资源
Spring MVC ⽀持 RESTful ⻛格请求,具体讲的就是使⽤ @PathVariable 注解获取 RESTful ⻛格的请求URL中的路径变量例子 :@RequestMapping(value = \"/handle/{id}\
web.xml中配置请求⽅式过滤器。配置见备注
Ajax Json交互
使⽤注解@RequstBody
@responseBody注解的作⽤是将controller的⽅法返回的对象通过适当的转换器转换为指定的格式之后,写⼊到response对象的body区注意:在使⽤此注解之后不会再⾛视图处理器,⽽是直接将数据写⼊到输⼊流中,他的效果等同于通过response对象输出指定格式的数据。
springmvc需要jar包,见备注
⾼级技术
拦截器(Inteceptor)
监听器、过滤器和拦截器对⽐
Servlet:处理Request请求和Response响应
过滤器(Filter):对Request请求起到过滤的作⽤,作⽤在Servlet之前,如果配置为/*可以对所有的资源访问(servlet、js/css静态资源等)进⾏过滤处理
监听器(Listener):随Web应⽤的启动⽽启动,只初始化⼀次,然后会⼀直运⾏监视,随Web应⽤的停⽌⽽销毁作⽤⼀:做⼀些初始化⼯作,web应⽤中spring容器启动ContextLoaderListener作⽤⼆:监听web中的特定事件,⽐如font color=\"#c41230\
拦截器(Interceptor):是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()⽅法。
多个拦截器的执⾏流程
当有多个拦截器同时⼯作时,它们的preHandle()⽅法会按照配置⽂件中拦截器的配置顺序执⾏,⽽它们的postHandle()⽅法和afterCompletion()⽅法则会按照配置顺序的反序执⾏。
处理multipart形式的数据
jar包 & 配置⽂件上传解析器 见备注
handler 见备注
在控制器中处理异常
@ControllerAdvice 捕捉所有异常
基于Flash属性的跨重定向请求数据传递
⼿写 MVC 框架
流程
具体见手写代码
源码深度剖析
前端控制器 DispatcherServlet 继承结构
处理请求的流程
1)调⽤getHandler()获取到能够处理当前请求的执⾏链 HandlerExecutionChain(Handler+拦截器)但是如何去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注册对象(multipartResolver)
SSM 整合
整合策略(Spring + Mybatis)+ SpringMVC
Mybatis整合Spring
整合⽬标数据库连接池以及事务管理都交给Spring容器来完成SqlSessionFactory对象应该放到Spring容器中作为单例对象管理Mapper动态代理对象交给Spring管理,我们从Spring容器中直接获得Mapper的代理对象整合所需 Jar 分析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数据库驱动jarDruid数据库连接池的jarPom坐标见备注
整合SpringMVC
引⼊pom坐标
扫描controller
附录
乱码问题解决
Post请求乱码,web.xml中加⼊过滤器
Get请求乱码(Get请求乱码需要修改tomcat下server.xml的配置)<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 条评论
回复 删除
下一页