ModelAndView的作用非常简单,就是两个作用。

第一个作用,往作用域中放值。

第二个作用,实现页面跳转。

15 - ModelAndView简单使用

往request作用域中放值,有三种方式。

springmvc中提供了一个类,就是modelandview。model是模型。项目中的实体类,装载传输数据。view是视图,帮助我们设置视图,操作视图。

day05-3-springmvc中ModelAndView的详解_spring

modelandview的构造器很多,如上图所示。

有参构造器当中的参数,说明modelandview的类当中,肯定是有对应的属性,肯定是有这些属性的set和get方法的。

day05-3-springmvc中ModelAndView的详解_spring_02

model-and-view的add-object方法

day05-3-springmvc中ModelAndView的详解_页面跳转_03

我们看上图中的,第二个方法。

我们说过model-and-view当中的model是用来装载和传输数据的。

那么里面addObject方法,就是装载和传输数据的过程。

day05-3-springmvc中ModelAndView的详解_作用域_04

我们前面通过return "success"这种方式,返回的就是视图名称。

现在我们通过modelAndView类setViewName的方法,也可以设置视图名称。

day05-3-springmvc中ModelAndView的详解_页面跳转_05

所以,我们必须将ModelAndView对象,返回:

day05-3-springmvc中ModelAndView的详解_作用域_06

我们在request作用域中放了一个值,然后跳转到了success.jsp,然后我们就可以在success.jsp当中获取到request作用域中的值。

jsp当中jstl是c标签

el表达式是为了从作用域中取值,pagecontext,request,session,Application四个作用域。从小到大逐个作用域寻找。

day05-3-springmvc中ModelAndView的详解_页面跳转_07

day05-3-springmvc中ModelAndView的详解_spring_08

我们可以加上作用域。

day05-3-springmvc中ModelAndView的详解_作用域_09

测试效果如下:

day05-3-springmvc中ModelAndView的详解_页面跳转_10

所以:modelandview的作用是装载数据,是往作用域中放置,view是设置视图名称,实现页面跳转。

16 - ModelAndView源码调试

加载spring-webmvc的源码,查看ModelAndView里面的东西。

day05-3-springmvc中ModelAndView的详解_页面跳转_11

我们看一下:

day05-3-springmvc中ModelAndView的详解_spring_12

day05-3-springmvc中ModelAndView的详解_杨博超-SSM_13

day05-3-springmvc中ModelAndView的详解_作用域_14

  • getModelInternal
  • getModelMap
  • getModel
  • 这三个方法是一样的,都是获取model对象,model就是一个map,就是多个键值对数据。

debug - 断点

day05-3-springmvc中ModelAndView的详解_作用域_15

day05-3-springmvc中ModelAndView的详解_作用域_16

day05-3-springmvc中ModelAndView的详解_spring_17

day05-3-springmvc中ModelAndView的详解_mvc_18

点击yes之后,进入到下面的视图:

day05-3-springmvc中ModelAndView的详解_mvc_19

调整视图布局,变成下面的样子:

day05-3-springmvc中ModelAndView的详解_mvc_20

  • 双击打断点,debug模式启动项目,进入debug视图,在debug框框中,显示的是,执行到断点位置,已经调用的方法。

day05-3-springmvc中ModelAndView的详解_页面跳转_21

1、DispatcherServlet.doDispatch(HttpServletRequest, HttpServletResponse)

day05-3-springmvc中ModelAndView的详解_作用域_22

  • 上面的代码中有一个mv,这个mv就是ModelAndView。
  • 我们的代码中,打断点的位置,是要返回一个ModelAndView对象。
  • 这里的代码,意思就是通过ha.handle()方法,对请求进行了处理,获得了一个mv对象。

day05-3-springmvc中ModelAndView的详解_作用域_23

为什么是空的,因为这一行,还没有开始执行。断点所在的位置,是还没有执行的。

day05-3-springmvc中ModelAndView的详解_杨博超-SSM_24

我们怎么从mv的代码的地方,走到processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);的地方呢?

day05-3-springmvc中ModelAndView的详解_作用域_25

我们想要从mv的地方跑到processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);的地方

  • 第一,我们可以通过step over一步一步执行。
  • 第二,我们可以在processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);位置,打一个断点,然后点击resume,就可以直接跳到我们需要的位置。

day05-3-springmvc中ModelAndView的详解_作用域_26

在这个位置,mv的值是,如下图所示:

day05-3-springmvc中ModelAndView的详解_spring_27

2、进入processDispatchResult方法内部

进入方法内部,两种方式:

  • 第一,按住ctrl键,鼠标点进去。
  • 第二,step into。如果当前位置,有多个方法被调用,会按照方法执行的顺序,一个一个地进入。

day05-3-springmvc中ModelAndView的详解_mvc_28

我们在render(mv, request, response);位置打一个断点,然后resume到render的位置,然后step into进去。

3、进入render方法内部

在这个render方法内部,已经把mv当中的view和model分开处理了。

day05-3-springmvc中ModelAndView的详解_作用域_29

view.render(mv.getModelInternal(), request, response);的位置,我们打一个断点,然后step into进入看看。

4、进入view.render()方法内部

view.render(mv.getModelInternal(), request, response);

这一行中有两个方法,render()是一个方法,mv.getModelInternal()也是一个方法。

我们点击step into之后,是mv.getModelInternal()这个方法先执行。

第一次,step into,进入mv.getModelInternal()方法内部。

day05-3-springmvc中ModelAndView的详解_spring_30

第二次,step into,回到render方法的位置。

day05-3-springmvc中ModelAndView的详解_页面跳转_31

第三次,step into,这次是真正进入到render方法内部:

day05-3-springmvc中ModelAndView的详解_mvc_32

5、进入renderMergedOutputModel()方法内部

day05-3-springmvc中ModelAndView的详解_spring_33

6、进入exposeModelAsRequestAttributes()方法内部

day05-3-springmvc中ModelAndView的详解_杨博超-SSM_34

然后不断step over,从这个exposeModelAsRequestAttributes()方法中出来。

7、回到renderMergedOutputModel()方法内部

ModelAndView的作用就是两个:第一往作用域中放值,第二实现页面跳转。

原来我们在servlet当中,往作用域中放值,和实现页面跳转,分别是这么写的。

request.setAttribute(key, value),往作用域中放值。

request.getRequestDispatcher.forward(),实现页面跳转

day05-3-springmvc中ModelAndView的详解_mvc_35

ModelAndView源码调试总结

day05-3-springmvc中ModelAndView的详解_杨博超-SSM_36

17 - 三种方式实现作用域放值

前面说过,往作用域中放值,是三种方式。

第一种方式

day05-3-springmvc中ModelAndView的详解_杨博超-SSM_37

	@RequestMapping(value="/param",method=RequestMethod.POST)
	public ModelAndView param() {
		ModelAndView mav = new ModelAndView();
		mav.addObject("username", "root");
		mav.setViewName("success");
		return mav;
	}

第二种方式

day05-3-springmvc中ModelAndView的详解_spring_38

	@RequestMapping(value="/param",method=RequestMethod.POST)
	public String param(Map<String, Object> map) {
		map.put("username", "admin");
		return "success";
	}

这种写法,默认也会将上面的map和return “success”包装成为ModelAndView对象的。

第三种方式

day05-3-springmvc中ModelAndView的详解_spring_39

	@RequestMapping(value="/param",method=RequestMethod.POST)
	public String param(Model model) {
		model.addAttribute("username", "zhangsan");
		return "success";
	}

通过model往作用域中放值,也会将model和"success"封装成为ModelAndView对象的

总结

springmvc处理请求过程中,往作用域中放值,有以下三种方式:

  • map.put("username","admin")
  • Model.addAttribute("username","admin")
  • ModelAndView.addObject("username","admin")

上面三种写法,都会和view一起封装到ModelAndView中。

当前乱码问题

  • 页面发送请求,传值张三

day05-3-springmvc中ModelAndView的详解_杨博超-SSM_40

  • 我们在控制层的方法当中,接收了页面传值,看到控制台输出是乱码的:

day05-3-springmvc中ModelAndView的详解_mvc_41

  • 作用域中放的值,页面显示是正常的。

day05-3-springmvc中ModelAndView的详解_mvc_42

为什么页面传值,控制层接收打印会乱码呢?

这是因为第一,页面传值的时候,默认会以页面的编码为编码格式。我们页面传过去的username默认是以utf-8编码的。

但是tomcat接收数据的时候,默认是用iso-8859-1来接收的。

springmvc为我们提供了一个编码过滤器,只要配置一下,就可以了。这个以后再说。

2019年6月17日 - day05 - 下午 - 结束
乖乖学习,好好做事。