模型数据
2023年11月15日大约 7 分钟约 1450 字
模型数据处理-数据放入Request域
说明
开发中,控制器/处理器中获取的数据如何放入 request 域,然后在前端(VUE/JSP/...)取出显示。
通过 HttpServletRequest 放入 request 域
创建 web\model_data.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>添加主人信息</h1>
<form action="vote/vote05" method="post">
主人号:<input type="text" name="id"><br>
主人名:<input type="text" name="name"><br>
宠物号:<input type="text" name="pet.id"><br>
宠物名:<input type="text" name="pet.name"><br>
<input type="submit" value="添加主人和宠物">
</form>
</body>
</html>
修改 VoteHandler.java
/**
* 1. 演示将提交的数据->springmvc封装到java对象->springmvc 会自动的将其放入到request域
* 2. 这样我们就可以在跳转到的页面取出数据.
*/
@RequestMapping(value = "/vote05")
public String test05(Master master, HttpServletRequest request) {
//1. springmvc会自动把获取的model模型,放入到request域中,名字就是master
//2. 也可以手动将master放入到request
request.setAttribute("address", "beijing");
//3. 如果我们希望修改master的属性值
master.setName("nono");
//4. 分析一下springmvc默认存放对象到request域中,属性名是
// request域 ("master", master) 属性名是类名/类型名 首字母小写
//返回到一个结果
return "vote_ok";
}
创建 web\WEB-INF\vote_ok.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>获取的的数据显示页面</h1>
<hr>
取出 request 域的数据 <br>
address: ${address}<br>
主人名字= ${requestScope.master.name}
主人信息= ${requestScope.master}
宠物名字= ${requestScope.master.pet.name}
</body>
</html>

通过请求的方法参数 Map<String,Object> 放入 request 域
修改 model_data.jsp
<br/>
<hr/>
<h1>添加主人信息[测试 Map ]</h1>
<form action="vote/vote06" method="post">
主人号:<input type="text" name="id"><br>
主人名:<input type="text" name="name"><br>
宠物号:<input type="text" name="pet.id"><br>
宠物名:<input type="text" name="pet.name"><br>
<input type="submit" value="添加主人和宠物">
</form>
修改 VoteHandler.java
/**
* 演示通过Map<String,Object> 设置数据到request域
*/
@RequestMapping(value = "/vote06")
public String test06(Master master, Map<String, Object> map) {
System.out.println("------test06-----");
//1. 需求是通过map对象,添加属性到request中
//2. 原理分析:springmvc会遍历map,然后将map的k-v, 存放到request域
map.put("address","zhengzhou");
//map.put("master", null); //页面取不出来 master了
//返回到一个结果
return "vote_ok";
}

通过返回 ModelAndView 对象 实现 request 域数据
修改 model_data.jsp
<br/>
<hr/>
<h1>添加主人信息[测试 ModelAndView]</h1>
<form action="vote/vote06" method="post">
主人号:<input type="text" name="id"><br>
主人名:<input type="text" name="name"><br>
宠物号:<input type="text" name="pet.id"><br>
宠物名:<input type="text" name="pet.name"><br>
<input type="submit" value="添加主人和宠物">
</form>
修改 VoteHandler.java
/**
* 演示通过返回ModelAndView对象,将数据放入到request域
*/
@RequestMapping(value = "/vote07")
public ModelAndView test07(Master master) {
System.out.println("----test07----");
ModelAndView modelAndView = new ModelAndView();
//放入属性到modelAndView对象
modelAndView.addObject("address","shanghai");
//modelAndView.addObject("master", null);
//可以把从数据库得到的数据->对象-》放入modelAndView[Service-dao-db]
//这里指定跳转的视图名称
modelAndView.setViewName("vote_ok");
//返回结果
return modelAndView;
}

注意事项
- 从本质看,请求响应的方法 return "xx",是返回了一个字符串,其实本质是返回了一个 ModelAndView 对象,只是默认被封装起来的。
- ModelAndView 即可以包含 model 数据,也可以包含视图信息。
- ModelAndView 对象的 addObject 方法可以添加 key-val 数据,默认在 request 域中。
- ModelAndView 对象 setView 方法可以指定视图名称。
模型数据处理-数据放入 Session域
说明
开发中,控制器/处理器中获取的数据如何放入 session 域,然后在前端(VUE/JSP/...)取出显示。
应用实例
修改 model_data.jsp
<br/>
<hr/>
<h1>添加主人信息[测试 Session]</h1>
<form action="vote/vote08" method="post">
主人号:<input type="text" name="id"><br>
主人名:<input type="text" name="name"><br>
宠物号:<input type="text" name="pet.id"><br>
宠物名:<input type="text" name="pet.name"><br>
<input type="submit" value="添加主人和宠物">
</form>
修改 VoteHandler.java
/**
* 演示如何将数据设置到session域中
*/
@RequestMapping(value = "/vote08")
public String test08(Master master, HttpSession httpSession) {
System.out.println("----test08----");
//master对象是默认放在request域
//我们将master对象放入到session域
httpSession.setAttribute("master",master);
httpSession.setAttribute("attribute", "guangzhou");
return "vote_ok";//请求转发
}
修改 vote_ok.jsp
<hr>
取出 session 域的数据 <br>
address: ${sessionScope.address}<br>
主人名字= ${sessionScope.master.name }
主人信息= ${sessionScope.master}

@ModelAttribute 实现 prepare 方法
说明
开发中,有时需要使用某个前置方法(比如 prepareXxx(),方法名由程序员定)给目标方法准备一个模型对象。
- @ModelAttribute 注解可以实现 这样的需求。
- 在某个方法上,增加了@ModelAttribute 注解后。
- 那么在调用该 Handler 的任何一个方法时,都会先调用这个方法。
应用实例
修改 VoteHandler.java
/**
* 1. 当Handler的方法被标识 @ModelAttribute,就视为一个前置方法
* 2. 当调用该Handler的其它的方法时,都会先执行该前置方法
* 3. 类似我们前面Spring中AOP的前置通知[底层是AOP机制]
* 4. prepareModel前置方法,会切入到其它方法前执行..
*/
@ModelAttribute
public void prepareModel(){
System.out.println("prepareModel()-----完成准备工作-----");
}

@ModelAttribute 最佳实践
- 在修改前,在前置方法中从数据库查出这个用户。
- 在修改方法(目标方法)中,可以使用前置方法从数据库查询的用户。
- 如果表单中对用户的某个属性修改了,则以新的数据为准,如果没有修改,则以数据库的信息为准,比如:用户的某个属性不能修改,就保持原来的值。