SpringMVC是如何实现作用域传值和页面跳转的?

15,521 阅读4分钟

作用域传值的4种方式

  • 通过 原生 HttpServletRequest 传值
  • 通过 ModelAndView 传值
  • 通过 Map 传值
  • 通过 Model 传值

注意:Map 和 Model 最终都会转换为 ModelAndView对象

通过 原生 HttpServletRequest 传值

img
img

通过 ModelAndView 传值

img
img

通过 Map 传值

img
img

通过 Model 传值

img
img

页面跳转的两种方式

img
img

forward请求转发2种方式(带参数)

Spring MVC中forward请求转发只需要请求一次服务器,可以提高访问速度,同时参数传递可以借助HttpServletRequest来处理,由于是处理同一个请求,所以request对象还是同一个,中文也不会出现乱码现象。使用forward后转到发某个请求而不是某个页面。

ViewResolver 请求转发

img
img
img
img

ModelAndView 请求转发

img
img
img
img

forward请求转发流程:客户首先发送一个请求到服务器端,服务器端发现匹配的servlet,并指定它去执行,当这个servlet执行完之后,它要调用getRequestDispacther()方法,把请求转发给指定的test.jsp,整个流程都是在服务器端完成的,而且是在同一个请求里面完的,因此servlet和jsp共享的是同一个request,在servlet里面放的所有东西,在jsp中都能取出来,因此,jsp能把结果getAttribute()出来。整个过程是一个请求,一个响应。

redirect重定向3种方式(带参数)

Spring MVC中做form表单功能提交时,防止用户客户端后退或者刷新时重复提交问题,需要在服务端进行重定向跳转,其中redirect是直接跳转到其他页面,有以下3种方法进行重定向。

redirect重定向流程

客户发送一个请求到服务器,服务器匹配servlet,这都和请求转发一样,servlet处理完之后调用了sendRedirect()这个方法,这个方法是response的方法,所以,当这个servlet处理完之后,看到response.senRedirect()方法,立即向客户端返回这个响应,响应行告诉客户端你必须要再发送一个请求,去访问test.jsp,紧接着客户端受到这个请求后,立刻发出一个新的请求,去请求test.jsp,这里两个请求互不干扰,相互独立,在前面request里面setAttribute()的任何东西,在后面的request里面都获得不了。可见,在sendRedirect()里面是两个请求,两个响应。

response.sendRedirect重定向跳转

img
img

ViewResolver直接跳转

img
img

携带参数的情况,参数将会拼接在URL的后面

img
img
img
img

ModelAndView 重定向

img
img
img
img
  1. redirect重定向可以跳转到任意服务器,可以用在系统间的跳转。
  2. Spring MVC中redirect重定向,参数传递可以直接拼接url也可以使用RedirectAttributes来处理,由于是不同的请求,重定向传递的参数会在地址栏显示,所以传递时要对中文编码进行处理。

ModelAndView 源码调试

ModelAndView类

ModelAndView中包含了一个model属性和一个view属性,model其实是一个ModelMap类型,它是一个LinkedHashMap的子类,view包含了一些视图信息。

ModelMap对象主要用于传递控制方法处理数据到结果页面,也就是说我们把结果页面上需要的数据放到ModelMap对象中即可,他的作用类似于request对象的setAttribute方法的作用(数据在一次请求转发中有效),用来在一个请求过程中传递处理的数据。

img
img
getModelInternal( ) 、  getModelMap( ) 、 getModel( ) 三个方法都是用来获得模型数据的。

ModelAndView处理模型数据

编写测试方法,return语句打断点,开始DeBug模式

img
img

进入到 DispatcherServlet 中的 doDispatch方法

调用请求处理器中的请求处理方法,方法执行后返回ModelAndView对象,被mv接收

img
img

回到Controller中请求的方法,执行return 语句,返回ModelAndView对象

img
img

再次进入到 DispatcherServlet 中的 doDispatch方法,准备处理ModelAndView

img
img

进入到 DispatcherServlet 中的ProcessDispatchResult方法

准备处理ModelAndView中的视图信息和模型数据

img
img

进入到 DispatcherServlet 中的render方法

首先根据ModelAndView中的视图信息,通过视图解析器,解析得到一个View视图对象

img
img

之后视图对象开始处理模型数据

img
img

进入到AbstractView中的render方法,准备整合输出的模型数据

img
img

render方法是View接口中定义的,在AbstractView中实现,所有具体的视图类都使用AbstractView中实现的render方法。

进入到InternalResourceView中的renderMergedOutputModel方法,准备将模型数据设置到request作用域中

img
img

进入到AbstractView中的exposeModelAsRequestAttributes方法,将模型数据添加到request作用域中

img
img

进入到InternalResourceView中的renderMergedOutputModel方法,获取转发器并实现转发

img
img