(spring-第21回【MVC基础篇】)SpringMVC一点就通
概述
- Spring MVC通过一套MVC注解,让POJO变成处理请求的控制器,无需实现任何接口,同时,SpringMVC还支持REST风格的URL请求:注解驱动和REST风格的Spring MVC是Spring 3.0最出彩的功能之一。
- Spring MVC框架围绕 DispatcherServlet这个核心展开,DispatcherServlet是SpringMVC的总导演,它负责截获请求,并将其分派给相应的处理器处理。
- 和大多数WEB MVC一样,Spring MVC通过一个前端Servlet接收所有的请求,并将具体工作委托给其他组件进行处理,DispatcherServlet就是Spring MVC的前端Servlet。
本文主要讲了一些什么
Spring MVC的基本原理 -->
用一个简单的示例对基本原理有个具体了解 -->
分别描述MVC的几个重量级角色:过滤请求、绑定请求、封装对象、处理XML和JSON、处理模型数据。
本篇文章重在知识点整合,作为读书笔记,语言简洁,删繁就简,由浅入深,引人入胜。通读本文,你将对Spring MVC有一个深入的了解。如果读,请深读。如果爱,请读完。
基本原理
基本原理及入门示例已在微信订阅号上发布,为防止原创性的冲突检测,故删去这一部分,详情扫码关注查看:

过滤请求
使用@RequestMapping可以过滤请求URL、请求参数、请求方法,请求头这4个方面的信息项。比如:

绑定请求信息到方法入参中
Spring MVC会将HTTP请求的信息绑定到相应的方法入参中,并根据方法返回值类型作出相应的后续处理。比如:

将请求信息封装成对象
使用HttpMessageConverter<T>可以将请求信息转换成一个对象,或者将对象输出为响应信息。(T就是对象类型)。
两把利剑:
1.使用RequestBody、ResponseBody。
2.使用HttpEntity<T>/ResponseEntity<T>
示例1:
客户端:

服务端:

示例2:
客户端:

服务端:

与RequestBody、ResponseBody不同的是,HttpEntity不仅可以访问请求、响应报文体的数据,还可以访问请求和响应报文头的数据。
示例1:
客户端:

服务端:

示例2:
客户端:

服务端:

怎么做到的?
HttpMessageConverter<T>提供了众多的实现类,它组成了一个功能强大、用途广泛的HttpMessageConverter<T>家族。
比如:
StringHttpMessageConverter负责将请求信息转换成字符串;
FormHttpMessageConverter负责将表单数据读取到MultiValueMap中;
还有诸如读写XML、Resource、JSON等等对应的实现类。
AnnotationMethodHandlerAdapter适配器默认装配了基本的Converter(String、ByteArray、Source、XmlAwareForm),容器会根据需要自动调用不同的HttpMessageConverter实现类。
如果不能满足需求,那么继续在xml中配置其他的converter:

处理XML和JSON
从上文可知,HttpMessageConverter有一个很强大的家族,能够处理各种格式的请求及响应。当然也可以处理XML和JSON。
处理XML和JSON的Converter分别是:
MarsHallingHttpMessageConverter(处理xml)。
Jaxb2RootElementHttpMessageConverter(同上,底层使用JAXB)。
MappingJacksonHttpMessageConverter(处理JSON)。
按照前文的思路,首先要在配置文件中装配好相应的Converter,但是还有其他必要的步骤:
步骤1:XML中配置Converter以及Marshaller:


步骤2:测试客户端发出请求:



步骤3:响应(服务)端:

步骤4:User的注解:

步骤5:用tcptrace监听测试
其实,如果把第92行和第93行代码的头部格式换成json,就变成传送json格式的数据了。这个时候,用tcptrace监听传送json的结果:

可以看到,请求中,我们的报文头格式变成了json,报文体也是json格式的。而响应中报文体也是json格式的。
为什么我直接截图了json格式的测试结果而没有测试请求xml的测试结果呢?
因为在xml测试时,报出了415 Unsupported media type的错误,尚未发现原因。
但是思路就是这样了。 读者如果知道“不支持此类型”的原因,欢迎评论留言。
处理模型数据
我们在Controller控制器中接收请求参数,把处理后得到的数据封装起来,然后返回到一个JSP,在JSP中就可以获取封装的数据。那么,在这个例子中,封装的数据就是模型数据,而JSP就是渲染模型数据的视图。这在MVC框架中是最重要的步骤。
在控制器方法中输出模型数据有四种方法:
方法一:ModelAndView
在控制器方法中新建ModelAndView对象,把“视图”和“模型数据”封装到该对象中,然后返回该对象即可。

方法二:@ModelAttribute
加到入参的前面,就自动把入参绑定为模型数据;加到方法A的前面,那么Spring MVC就会在执行任何目标处理方法之前,先执行方法A(B\C等等),然后把这些加了标注的方法的返回值绑定为模型数据。
举例1:

Spring MVC会先把模型数据储存到ServletRequest的属性列表中(使用setAttribute保存)。
然后在返回的jsp(视图对象)中,使用${user.userName}来访问user的属性。
举例2:

在执行handle62之前,spring扫描到有方法头部标注了@ModelAttribute,那么,spring就会先去执行getUser,并把返回值user作为模型数据,键为”user”。
这时执行handle62,入参前面的@ModelAttribute键为”user”,正好匹配了刚封装的模型数据的键,那么就把模型数据赋值给入参User user,然后285行对user做了覆盖操作,最后交给视图层处理。
方法三:Map and Model
如果处理方法的入参类型为Map或者Model(或者具备二者功能的对象如:ModelMap),那么spring会将隐含的模型数据传给该入参,在处理方法中,我们可以从该入参中取出隐含的模型数据,也可以继续添加模型数据。

标注了@ModelAttribute的方法的返回值(getUser方法返回的user)就是隐含的模型数据。
由于handle63的入参为ModelMap类型,所以,spring会把user这个隐含模型数据授予modelMap,在300行,我们通过该入参取出模型数据,在302行,我们通过该入参继续添加模型数据。
方法四:@SessionAttributes
如果Controller类的头部标注了@SessionAttributes(”xxx”),那么spring会把键为xxx的模型数据暂存到HttpSession中,以便多个请求之间可以共享该数据。

... ...

61行的标注表示:后面处理器在处理任何方法时,看到属性名为user的模型属性就会把它存到session中共享。由于328行把user作为了模型数据,那么这个user就放到了session中。
当转发请求到handle72时,就可以从modelMap中拿到该对象。
当使用完成时,在338行表示把该对象从session中移除。否则它会一直存在。
然而程序是跑不起来的,会报HttpSessionRequiredException。为什么呢?
这是因为,如果有了61行标注的会话属性user,那么spring就会尝试从会话中获取该属性,然后把它赋给入参。
也就是说,spring看到61行的标注,会从会话中找user为键的模型数据,找到后把它赋值给334行的modelMap。
但是现在从代码看来,在执行61行标注之前,会话中并没有键为user的模型数据。
所以,解决方法很简单:
只需要像方法二那样,加一个:

就好了。这样,在执行61行之前,先执行getUser,把user作为隐含模型数据。那么执行61行时,该会话中就已经有user了。
当你读到这里,你已经百毒不侵了。亲,不点个赞吗?
(spring-第21回【MVC基础篇】)SpringMVC一点就通的更多相关文章
- spring 5.x 系列第2篇 —— springmvc基础 (代码配置方式)
文章目录 一.搭建hello spring工程 1.1 项目搭建 1.2 相关注解说明 二.配置自定义拦截器 三.全局异常处理 四.参数绑定 4.1 参数绑定 4.2 关于日期格式转换的三种方法 五. ...
- spring 5.x 系列第1篇 —— springmvc基础 (xml配置方式)
文章目录 一.搭建hello spring工程 1.1 项目搭建 1.2 相关配置讲解 二.配置自定义拦截器 三.全局异常处理 四.参数绑定 4.1 参数绑定 4.2 关于日期格式转换的三种方法 五. ...
- Spring MVC 基础篇4
Spring MVC Controller中返回数据到页面 1.使用ModelAndView 进行数据返回到请求页面 2.利用Map类型的入参进行Controller返回到页面上 3.将数据放到Ses ...
- Spring MVC基础篇4
Spring MVC操作原生Servlet 对象 Spring MVC 可以操作原生的Servlet API,如下的这些原生API,可以各自 自由混合使用,也可以和其他非原生 参数组合使用 实例代码: ...
- MVC基础篇—控制器与视图数据的传递
Viewdata,Viewbag,Tempdata 1 Vewdata:简单来说就是数据字典,通过键值对的形式来存放数据.举例如下: //后台控制器代码: public ActionResult V ...
- Java基础-SSM之Spring MVC入门篇
Java基础-SSM之Spring MVC入门篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Spring MVC简介 1>.什么是Spring MVC 答:Sprin ...
- Spring+SpringMVC+MyBatis+easyUI整合基础篇(一)项目简介
很久之前就打算开始写一下自己的技术博客了,实在抽不出时间所以计划一直搁置了,最近项目进度渐渐缓了下来,不那么忙了,也因此开始筹备自己的博客.说到这次博客的主角,也是无心插柳找到的,来源于两年前自己写的 ...
- Spring+SpringMVC+MyBatis+easyUI整合基础篇(六)maven整合SSM
写在前面的话 承接前文<Spring+SpringMVC+MyBatis+easyUI整合基础篇(五)讲一下maven>,本篇所讲述的是如何使用maven与原ssm项目整合,使得一个普 ...
- Spring+SpringMVC+MyBatis+easyUI整合基础篇(八)mysql中文查询bug修复
写在前面的话 在测试搜索时出现的问题,mysql通过中文查询条件搜索不出数据,但是英文和数字可以搜索到记录,中文无返回记录.本文就是写一下发现问题的过程及解决方法.此bug在第一个项目中点这里还存在, ...
随机推荐
- 几款极好的 JavaScript 文件上传插件
文件上传功能作为网页重要的组成部分,几乎无处不在,从简单的单个文件上传到复杂的批量上传.拖放上传,需要开发者花费大量的时间和精力去处理,以期实现好用的上传功能.这篇文章向大家推荐几款很棒的 JavaS ...
- c#数据绑定(2)——删除DataTable的数据
文/嶽永鹏 c#数据绑定(1)中,简要的通过代码应用了DataTable,DataTableColumns,DataTableRow类,通过UI界面的Textbox向DataTable中添加数据然后响 ...
- 20169212《Linux内核原理与分析》 第十周作业
云课堂回顾学习 1. 进程调度的时机 中断处理过程(包括时钟中断.I/O中断.系统调用和异常)中,直接调用schedule(),或者返回用户态时根据need_resched标记调用schedule() ...
- datagrid 禁止点击行
var s = $("#dg").datagrid('getPanel'); var rows = s.find('tr.datagrid-row'); ...
- python【6】-函数式编程
一.高阶函数 map,reduce 1.map() 函数接收两个参数,一个是函数,一个是序列,map将传入的函数依次作用到序列的每个元素,并把结果作为新的list返回. def f(x): retur ...
- Linux上如何执行java程序
想要在Ubuntu上运行java程序,可以将java程序编译成功后打包,然后在Ubuntu上用命令执行jar文件 具体操作如下: 1.Windows上使用eclipse编译java工程,编译完成后导出 ...
- IOS多媒体
概览 随着移动互联网的发展,如今的手机早已不是打电话.发短信那么简单了,播放音乐.视频.录音.拍照等都是很常用的功能.在iOS中对于多媒体的支持是非常强大的,无论是音视频播放.录制,还是对麦克风.摄像 ...
- hibernate入门实例
1. 环境配置 1.1 hiberante环境配置 hibernate可实现面向对象的数据存储.hibernate的官网:http://hibernate.org/ 官网上选择hibernate OR ...
- js只保留整数,向上取整,四舍五入,向下取整等函数
1.丢弃小数部分,保留整数部分 parseInt(5/2) 2.向上取整,有小数就整数部分加1 Math.ceil(5/2) 3.四舍五入. Math.round(5/2) 4.向下取整 Math.f ...
- Redux教程1:环境搭建,初写Redux
如果将React比喻成士兵的话,你的程序还需要一位将军,去管理士兵(的状态),而Redux恰好是一位好将军,简单高效: 相比起React的学习曲线,Redux的稍微平坦一些:本系列教程,将以" ...