作者:雷丶冷凝 | 来源:互联网 | 2023-10-11 04:35
文章内容输出来源:拉勾教育Java高薪训练营。简介SpringMVC是Spring给我们提供的⼀个⽤于简化Web开发的框架。在说SpringMVC前,我们需要了解下什么是MVC
文章内容输出来源:拉勾教育Java高薪训练营。
简介 Spring MVC 是 Spring 给我们提供的⼀个⽤于简化 Web 开发的框架。在说Spring MVC前,我们需要了解下什么是MVC架构以及三层架构?
1 MVC 体系结构 三层架构
在 JavaEE 开发中,⼏乎全都是基于 B/S 架构的开发。那么在 B/S 架构中,系统标准的三层架构包括:表现层、业务层、持久层。 三层架构中,每⼀层各司其职,接下来我们就说说每层都负责哪些⽅⾯:表现层 :也就是我们常说的web 层。它负责接收客户端请求,向客户端响应结果,通常客户端使⽤http 协议请求web 层,web 需要接收 http 请求,完成 http 响应。表现层包括展示层和控制层:控制层负责接收请求,展示层负责结果的展示。表现层的设计⼀般都使⽤ MVC 模型。(MVC 是表现层的设计模型,和其他层没有关系)。业务层 :也就是我们常说的 service 层。它负责业务逻辑处理,和我们开发项⽬的需求息息相关。web 层依赖业务层,但是业务层不依赖 web 层。业务层在业务处理时可能会依赖持久层,如果要对数据持久化需要保证事务⼀致性。(也就是我们说的, 事务应该放到业务层来控制)持久层 :也就是我们是常说的 dao 层。负责数据持久化,包括数据层即数据库和数据访问层,数据库是对数据进⾏持久化的载体,数据访问层是业务层和持久层交互的接⼝,业务层需要通过数据访问层将数据持久化到数据库中。通俗的讲,持久层就是和数据库交互,对数据库表进⾏增删改查的。
MVC设计模式
MVC 全名是 Model View Controller,是 模型(model)-视图(view)-控制器(controller) 的缩写, 是⼀ 种⽤于设计创建 Web 应⽤程序表现层的模式。MVC 中每个部分各司其职:Model(模型) :模型包含业务模型和数据模型,数据模型⽤于封装数据,业务模型⽤于处理业务。View(视图) : 通常指的就是我们的 jsp 或者 html。作⽤⼀般就是展示数据的。通常视图是依据模型数据创建的。Controller(控制器) : 是应⽤程序中处理⽤户交互的部分。作⽤⼀般就是处理程序逻辑的。MVC提倡:每⼀层只编写⾃⼰的东⻄,不编写任何其他的代码;分层是为了解耦,解耦是为了维护⽅便和分⼯协作。
2 Spring MVC 是什么? SpringMVC 全名叫 Spring Web MVC,是⼀种基于 Java 的实现 MVC 设计模型的请求驱动类型的轻量级Web 框架,属于 SpringFrameWork 的后续产品。
Spring MVC 本质可以认为是对servlet的封装,简化了我们serlvet的开发。 作⽤:(1)接收请求 (2)返回响应,跳转⻚⾯
Spring MVC ⼯作流程 需求:前端浏览器请求url:http://localhost:8080/demo/handle01,前端⻚⾯显示后台服务器的时间开发过程 1)配置DispatcherServlet前端控制器 2)开发处理具体业务逻辑的Handler(@Controller、@RequestMapping) 3)xml配置⽂件配置controller扫描,配置springmvc三⼤件 4)将xml⽂件路径告诉springmvc(DispatcherServlet)
Spring MVC 请求处理流程 第⼀步:⽤户发送请求⾄前端控制器DispatcherServlet 第⼆步:DispatcherServlet收到请求调⽤HandlerMapping处理器映射器 第三步:处理器映射器根据请求Url找到具体的Handler(后端控制器),⽣成处理器对象及处理器拦截器(如果 有则⽣成)⼀并返回DispatcherServlet 第四步:DispatcherServlet调⽤HandlerAdapter处理器适配器去调⽤Handler 第五步:处理器适配器执⾏Handler 第六步:Handler执⾏完成给处理器适配器返回ModelAndView 第七步:处理器适配器向前端控制器返回 ModelAndView,ModelAndView 是SpringMVC 框架的⼀个底层对 象,包括 Model 和 View 第⼋步:前端控制器请求视图解析器去进⾏视图解析,根据逻辑视图名来解析真正的视图。 第九步:视图解析器向前端控制器返回View 第⼗步:前端控制器进⾏视图渲染,就是将模型数据(在 ModelAndView 对象中)填充到 request 域 第⼗⼀步:前端控制器向⽤户响应结果
3 Spring MVC 九⼤组件 HandlerMapping(处理器映射器) HandlerAdapter(处理器适配器) HandlerExceptionResolver(处理 Handler 产⽣的异常情况) ViewResolver(视图解析器) RequestToViewNameTranslator(请求地址自动映射跳转视图名转换器) LocaleResolver(国际化解析器) ThemeResolver(主题解析器) MultipartResolver(文件上传请求解析器) FlashMapManager(重定向时的参数传递管理器) 4 SpringMVC请求参数绑定 默认⽀持 Servlet API 作为⽅法参数,只需要直接声明形参即可 当需要使⽤HttpServletRequest、HttpServletResponse、HttpSession等原⽣servlet对象时,直接在handler⽅法中形参声明使⽤即可。
@RequestMapping ( "/handle02" ) public ModelAndView handle02 ( HttpServletRequest request, HttpServletResponse response, HttpSession session) { }
绑定简单类型参数,只需要直接声明形参即可 简单数据类型:⼋种基本数据类型及其包装类型 参数类型推荐使⽤包装数据类型,因为基础数据类型不可以为null 整型:Integer、int 字符串:String 单精度:Float、float 双精度:Double、double 布尔型:Boolean、boolean 说明:对于布尔类型的参数,请求的参数值为true或false。或者1或0 注意:绑定简单数据类型参数,只需要直接声明形参即可(形参参数名和传递的参数名要保持⼀致,建议 使⽤包装类型,当形参参数名和传递参数名不⼀致时可以使⽤@RequestParam注解进⾏⼿动映射)
@RequestMapping ( "/handle03" ) public ModelAndView handle03 ( @RequestParam ( "ids" ) Integer id, Boolean flag) { }
绑定Pojo类型参数 接收pojo类型参数,直接形参声明即可,类型就是Pojo的类型,形参名⽆所谓,但是要求传递的参数名必须和Pojo的属性名保持⼀致
@RequestMapping ( "/handle04" ) public ModelAndView handle04 ( User user) { }
绑定Pojo包装对象参数 不管包装Pojo与否,它⾸先是⼀个pojo,那么就可以按照上述pojo的要求来 (1)绑定时候直接形参声明即可 (2)传参参数名和pojo属性保持⼀致,如果不能够定位数据项,那么通过属性名 + “.” 的⽅式进⼀步锁定数据
绑定⽇期类型参数(需要配置⾃定义类型转换器) 前端
< fieldset> < p> 测试⽤例:SpringMVC接收⽇期类型参数< / p> < a href= "/demo/handle06?birthday=2019-10-08" > 点击测试< / a> < / fieldset>
后端,定义⼀个SpringMVC的类型转换器 接⼝,扩展实现接⼝接⼝,注册你的实现
package com. lagou. edu. converter; import org. springframework. core. convert. converter. Converter; import java. text. ParseException; import java. text. SimpleDateFormat; import java. util. Date; public class DateConverter implements Converter < String, Date> { @Override public Date convert ( String source) { SimpleDateFormat simpleDateFormat = new SimpleDateFormat ( "yyyy-MM-dd" ) ; try { Date parse = simpleDateFormat. parse ( source) ; return parse; } catch ( ParseException e) { e. printStackTrace ( ) ; } return null; } }
配置文件注册⾃定义类型转换器
< mvc: annotation-driven conversionservice = " conversionServiceBean" /> < bean id = " conversionServiceBean" class = " org.springframework.format.support.FormattingConversionServiceFactoryBean" > < property name = " converters" > < set> < bean class = " com.lagou.edu.converter.DateConverter" > bean> set> property> bean>
controller方法
@RequestMapping ( "/handle06" ) public ModelAndView handle06 ( Date birthday) { }
5 SpringMVC与Ajax Json交互 @ResponseBody注解
@responseBody注解的作⽤是将controller的⽅法返回的对象通过适当的转换器转换为指定的格式之后,写⼊到response对象的body区,通常⽤来返回JSON数据或者是XML数据。 注意:在使⽤此注解之后不会再⾛视图处理器,⽽是直接将数据写⼊到输⼊流中,他的效果等同于通过response对象输出指定格式的数据。
Spring MVC 使⽤ Json 交互
所需jar包
< dependency> < groupId> com.fasterxml.jackson.core groupId> < artifactId> jackson-core artifactId> < version> 2.9.0 version> dependency> < dependency> < groupId> com.fasterxml.jackson.core groupId> < artifactId> jackson-databind artifactId> < version> 2.9.0 version> dependency> < dependency> < groupId> com.fasterxml.jackson.core groupId> < artifactId> jackson-annotations artifactId> < version> 2.9.0 version> dependency>
前端jsp⻚⾯及js代码
< div> < h2> Ajax json交互 h2> < fieldset> < input type = " button" id = " ajaxBtn" value = " ajax提交" /> fieldset> div>
$ ( function ( ) { $ ( "#ajaxBtn" ) . bind ( "click" , function ( ) { $. ajax ( { url: '/demo/handle07' , type: 'POST' , data: '{"id":"1","name":"李四"}' , contentType: 'application/json;charset=utf-8' , dataType: 'json' , success: function ( data) { alert ( data. name) ; } } ) } ) } )
后台Handler⽅法
@RequestMapping ( "/handle07" ) public @ResponseBody User handle07 ( @RequestBody User user) { user. setName ( "张三丰" ) ; return user; }
6 SpringMVC之拦截器 监听器、过滤器和拦截器对⽐
过滤器(Filter) :对Request请求起到过滤的作⽤,作⽤在Servlet之前,如果配置为/*可以对所有的资源访问(servlet、js/css静态资源等)进⾏过滤处理监听器(Listener) :实现了javax.servlet.ServletContextListener 接⼝的服务器端组件,它随Web应⽤的启动⽽启动,只初始化⼀次,然后会⼀直运⾏监视,随Web应⽤的停⽌⽽销毁 作⽤⼀:做⼀些初始化⼯作,web应⽤中spring容器启动ContextLoaderListener 作⽤⼆:监听web中的特定事件,⽐如HttpSession,ServletRequest的创建和销毁;变量的创建、销毁和修改等。可以在某些动作前后增加处理,实现监控,⽐如统计在线⼈数,利⽤HttpSessionLisener等。拦截器(Interceptor) :是SpringMVC、Struts等表现层框架⾃⼰的,不会拦截jsp/html/css/image的访问等,只会拦截访问的控制器⽅法(Handler)。
从配置的⻆度也能够总结发现:serlvet、filter、listener是配置在web.xml中的,⽽interceptor是配置在表现层框架⾃⼰的配置⽂件中的拦截器的执⾏流程
在运⾏程序时,拦截器的执⾏是有⼀定顺序的,该顺序与配置⽂件中所定义的拦截器的顺序相关。 单个拦截器,在程序中的执⾏流程如下图所示: 1)程序先执⾏preHandle()⽅法,如果该⽅法的返回值为true,则程序会继续向下执⾏处理器中的⽅法,否则将不再向下执⾏。 2)在业务处理器(即控制器Controller类)处理完请求后,会执⾏postHandle()⽅法,然后会通过DispatcherServlet向客户端返回响应。 3)在DispatcherServlet处理完请求后,才会执⾏afterCompletion()⽅法。
多个拦截器的执⾏流程
多个拦截器(假设有两个拦截器Interceptor1和Interceptor2,并且在配置⽂件中, Interceptor1拦截器配置在前),在程序中的执⾏流程如下图所示: 从图可以看出,当有多个拦截器同时⼯作时,它们的preHandle()⽅法会按照配置⽂件中拦截器的配置顺序执⾏,⽽它们的postHandle()⽅法和afterCompletion()⽅法则会按照配置顺序的反序执⾏。
乱码问题解决 Post请求乱码,web.xml中加⼊过滤器
< filter> < filter-name> encoding filter-name> < filter-class> org.springframework.web.filter.CharacterEncodingFilter filter-class> < init-param> < param-name> encoding param-name> < param-value> UTF-8 param-value> init-param> < init-param> < param-name> forceEncoding param-name> < param-value> true param-value> init-param> filter> < filter-mapping> < filter-name> encoding filter-name> < url-pattern> /* url-pattern> filter-mapping>
Get请求乱码(Get请求乱码需要修改tomcat下server.xml的配置)
< Connector URIEncoding = " utf-8" connectionTimeout = " 20000" port = " 8080" protocol = " HTTP/1.1" redirectPort = " 8443" />