概述

  • 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一点就通的更多相关文章

  1. spring 5.x 系列第2篇 —— springmvc基础 (代码配置方式)

    文章目录 一.搭建hello spring工程 1.1 项目搭建 1.2 相关注解说明 二.配置自定义拦截器 三.全局异常处理 四.参数绑定 4.1 参数绑定 4.2 关于日期格式转换的三种方法 五. ...

  2. spring 5.x 系列第1篇 —— springmvc基础 (xml配置方式)

    文章目录 一.搭建hello spring工程 1.1 项目搭建 1.2 相关配置讲解 二.配置自定义拦截器 三.全局异常处理 四.参数绑定 4.1 参数绑定 4.2 关于日期格式转换的三种方法 五. ...

  3. Spring MVC 基础篇4

    Spring MVC Controller中返回数据到页面 1.使用ModelAndView 进行数据返回到请求页面 2.利用Map类型的入参进行Controller返回到页面上 3.将数据放到Ses ...

  4. Spring MVC基础篇4

    Spring MVC操作原生Servlet 对象 Spring MVC 可以操作原生的Servlet API,如下的这些原生API,可以各自 自由混合使用,也可以和其他非原生 参数组合使用 实例代码: ...

  5. MVC基础篇—控制器与视图数据的传递

    Viewdata,Viewbag,Tempdata 1  Vewdata:简单来说就是数据字典,通过键值对的形式来存放数据.举例如下: //后台控制器代码: public ActionResult V ...

  6. Java基础-SSM之Spring MVC入门篇

    Java基础-SSM之Spring MVC入门篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Spring MVC简介 1>.什么是Spring MVC 答:Sprin ...

  7. Spring+SpringMVC+MyBatis+easyUI整合基础篇(一)项目简介

    很久之前就打算开始写一下自己的技术博客了,实在抽不出时间所以计划一直搁置了,最近项目进度渐渐缓了下来,不那么忙了,也因此开始筹备自己的博客.说到这次博客的主角,也是无心插柳找到的,来源于两年前自己写的 ...

  8. Spring+SpringMVC+MyBatis+easyUI整合基础篇(六)maven整合SSM

    写在前面的话   承接前文<Spring+SpringMVC+MyBatis+easyUI整合基础篇(五)讲一下maven>,本篇所讲述的是如何使用maven与原ssm项目整合,使得一个普 ...

  9. Spring+SpringMVC+MyBatis+easyUI整合基础篇(八)mysql中文查询bug修复

    写在前面的话 在测试搜索时出现的问题,mysql通过中文查询条件搜索不出数据,但是英文和数字可以搜索到记录,中文无返回记录.本文就是写一下发现问题的过程及解决方法.此bug在第一个项目中点这里还存在, ...

随机推荐

  1. SPSS数据分析—多分类Logistic回归模型

    前面我们说过二分类Logistic回归模型,但分类变量并不只是二分类一种,还有多分类,本次我们介绍当因变量为多分类时的Logistic回归模型. 多分类Logistic回归模型又分为有序多分类Logi ...

  2. [HTML/HTML5]6 使用图像

    6.1  将图像作为Web页面的前景元素 使用img元素,就可以在Web页面中添加图像.img是image的缩写.只需在img元素中添加src(source的缩写)属性,并为该属性设置相应的值,就可以 ...

  3. Linux FTP的安装与配置

    Linux FTP的安装与配置   ftp安装部分,操作步骤如下: 可以使用yum命令直接安装ftp # yum install vsftpd ftp服务的开启与关闭命令: 开启:# service  ...

  4. MySQL JDBC/MyBatis Stream方式读取SELECT超大结果集

    情景: 遍历并处理一个大表中的所有数据, 这个表中的数据可能会是千万条或者上亿条, 很多人可能会说用分页limit……但需求本身一次性遍历更加方便, 且Oracle/DB2都有方便的游标机制. 对DB ...

  5. Mina的ProtocolEncoderOutput之坑

    这个问题是之前测试上万个连接的pingpong发现的,调了很久,但当时急着做其他事,就没有详细记录下来,现在回想起来也有点记不清具体哪儿了. 表现是在测试上万个连接的pingpong时会出现服务器挂起 ...

  6. oracle当前的连接数

    怎样查看oracle当前的连接数呢?只需要用下面的SQL语句查询一下就可以了. select * from v$session where username is not null select us ...

  7. u盘文件恢复

    同事的一个u盘,在别的机器上用过之后,插到自己的机器上,被360报警有木马,处理完后,一些文件和文件夹不见了. 拿到我的机器上,360弹出框问要不要处理,列表里显示有几个文件夹被隐藏起来了,选择显示后 ...

  8. CSS3新增的选择器和属性

    <!doctype html>无标题文档 一.新增的选择器 CSS3新增的属性选择器 {除ie6外的大部分浏览器支持) 序号 选择器 含义 实例 1 E[att^="val&qu ...

  9. SpringMVC Model

    处理模型数据 ModelAndView:处理方法返回值类型为ModelAndView时,方法体即可通过该对象添加模型数据. @ModelAttribute:方法入参标注了该注解后,入参对象会放到数据模 ...

  10. Python中的深浅拷贝

    1.什么是深浅拷贝? python中一切皆对象,python中的数字.字符串.元组等,如果存放在了内存中,这部分内存里面的内容是不会改变的,但是也有情况,内存中存放了可变对象,比如说列表和字典,他们的 ...