Spring MVC - 如何处理模型数据(ModelAndView、Map&Model、@SessionAttributes、@ModelAttribute)

小编 2026-06-21 阅读:115 评论:0
这里主要说的是,客户端请求服务端的时候,服务端的数据是如何返回给客户端的。 Spring MVC 提供了以下几种途径输出模型数据: ModelAndView: 处理方法返回值类型为 ModelAndVi...

这里主要说的是,客户端请求服务端的时候,服务端的数据是如何返回给客户端的。

Spring MVC 提供了以下几种途径输出模型数据:

  • ModelAndView: 处理方法返回值类型为 ModelAndView时, 方法体即可通过该对象添加模型数据
  • Map 及 Model: 目标方法入参为org.springframework.ui.Model、org.springframework.ui.ModelMap 或 java.uti.Map 时,处理方法返回时Map中的数据会自动添加到模型中。

@SessionAttributes: 将模型中的某个属性暂存到HttpSession 中,以便多个请求之间可以共享这个属性

  • @ModelAttribute: 方法入参标注该注解后, 入参的对象就会放到数据模型中

ModelAndView:

控制器处理方法的返回值如果为 ModelAndView, 则其既包含视图信息,也包含模型数据信息。

添加模型数据:
      MoelAndView addObject(String attributeName, ObjectattributeValue)

     ModelAndView addAllObject(Map<String, ?> modelMap)

设置视图:

     void setView(View view)

     void setViewName(String viewName)

代码示例:

// index.jsp

<!-- 测试 目标方法返回值可以是 ModelandView 类型 -->
<a href=\"testModelAndView\">Test ModelAndView</a>

// Controller 
/**
  * 测试 目标方法返回值可以是 ModelandView 类型
  * 其中可以包含视图和模型信息
  * @return
  */
@RequestMapping(value=\"/testModelAndView\")
public ModelAndView testModelAndView() {
	String viewName = SUCCESS;
	// 添加模型数据到 ModelAndView 中
	ModelAndView modelAndView = new ModelAndView(viewName );
	modelAndView.addObject(\"time\", new Date());
	return modelAndView;
}

// success.jsp
<%@ page language=\"java\" contentType=\"text/html; charset=UTF-8\"
    pageEncoding=\"UTF-8\"%>
<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">
<html>
	<head>
		<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">
	<title>Insert title here</title>
</head>
	<body>
		<h4>SUCCESS PAGE</h4>
		
		time : ${time} }
	</body>
</html>

问题1:这个过程是如何实现的?

大致是这样的,Spring MVC 最终会遍历一个Map,将我们放入ModelAndView中的 model 中的键值放入请求域中,注意是 request 请求域。这部分可以查看源码。这里就不贴了。

 Map 及 Model

Spring MVC 在内部使用了一个org.springframework.ui.Model 接口存储模型数据

具体步骤

Spring MVC 在调用方法前会创建一个隐含的模型对象作为模型数据的存储容器。

如果方法的入参为 Map 或 Model 类型,Spring MVC 会将隐含模型的引用传递给这些入参。在方法体内,开发者可以通过这个入参对象访问到模型中的所有数据,也可以向模型中添加新的属性数据

代码示例:

index.jsp
<!-- 测试 目标方法入参 可以是 Map 或 Model 类型 -->
<a href=\"testMap\">Test Map</a>


/**
  * 测试 目标方法可以添加 Map 类型(实际上也可以是 Model 或 ModelMap 类型)的参数
  * 
  * @param map
  * @return
  */
@RequestMapping(value=\"/testMap\")
public String testMap(Map<String, Object> map) {
	System.out.println(map.getClass().getName());
	map.put(\"names\", Arrays.asList(\"tom\",\"Jerry\", \"Mike\"));
	return SUCCESS;
}

success.jsp

names:${names }

 @SessionAttributes

若希望在多个请求之间共用某个模型属性数据,则可以在控制器类上标注一个 @SessionAttributes, Spring MVC将在模型中对应的属性暂存到 HttpSession 中。
• @SessionAttributes 除了可以通过属性名指定需要放到会话中的属性外,还可以通过模型属性的对象类型指定哪些模型属性需要放到会话中
– @SessionAttributes(types=User.class) 会将隐含模型中所有类型为 User.class 的属性添加到会话中。
– @SessionAttributes(value={“user1”, “user2”})
– @SessionAttributes(types={User.class, Dept.class})
– @SessionAttributes(value={“user1”, “user2”},types={Dept.class})

代码示例:

index.jsp

<!-- 测试 @SessionAttributes 注解 -->
<a href=\"testSessionAttributes\">Test SessionAttributes</a>


Controller
@SessionAttributes(value = \"user\", types= {String.class}) // 这里的 value值 user 与 目标方法 map 中的键一致
public class SpringMvcTest {
   /**
    * 测试 @SessionAttributes 注解
    * 注意:该注解只能放在类上面
    * @param map
    * @return
    */
    @RequestMapping(value=\"/testSessionAttributes\")
    public String testSessionAttributes(Map<String, Object> map) {
	    User user = new User(\"Tom\", \"123456\", \"tom@atguigu.com\", \"12\");
	    map.put(\"user\", user);
	    map.put(\"school\", \"school\");
	    return SUCCESS;
    }
}


success.jsp

request user:${requestScope.user }
<br>
<br>
Session user:${sessionScope.user }
		
<br>
<br>
request school:${requestScope.school }
<br>
<br>
Session school:${sessionScope.school }

@ModelAttribute

使用场景:

修改数据库某条记录,但是某些字段不允许修改。

将修改之后的数据由页面表单传入后台,错误场景是新创建出来的一个对象,将这个新建的对象的值赋给原数据对应的记录,导致有些值修改之后变为null,丢失

\"\"

错误场景代码示例

 

index.jsp

<!-- 
	模拟修改操作
	1. 原有数据为:1, Tom, 123456, tom@atguigu.com, 15
	2. 密码不能被修改
	3. 表单回回显, 模拟操作直接在表单填写对应的属性值
-->
<form action=\"testModelAttribute\" method=\"post\">
	<input type=\"hidden\" name=\"id\" value=\"1\"/>
	 	
	username:<input type=\"text\" name=\"username\" value=\"Tom\"/> 
	<br>
	<!-- password:<input type=\"password\" name=\"password\"/> -->
	<br>
	email:<input type=\"text\" name=\"email\" value=\"tom@atguigu.com\"/>
	<br>
	age:<input type=\"text\" name=\"age\"/>
	<br>
	<input type=\"submit\" value=\"Test ModelAttribute\" />
</form>

Controller

@Controller
public class SpringMvcTest {
	
	private static final String SUCCESS = \"success\";
	
	/**
	 * 
	 * @param user
	 * @return
	 */
	@RequestMapping(value=\"/testModelAttribute\")
	public String testModelAttribute(User user) {
		System.out.println(\"修改: \" + user);
		return SUCCESS;
	}
}

正确是对象应该是从数据库先查出来,将表单的值赋给该对象,这样就不会导致数据丢失

\"\"

 注解 @ModelAttribute 可以实现上述功能。

Controller 代码示例(新增一个被 @ModelAttribute注解标记的方法),其他不变

/**
 * 由 @ModelAttribute 注解标记的方法,会在每个目标方法执行之前被 Spring MVC 调用!
 * 
 * 注意 在 @ModelAttribue 修饰的方法中,放入到 Map 时的键需要和目标方法入参类型的第一个字母小写的字符串一致
 * @param id
 * @param map
 */
@ModelAttribute
public void getUser(@RequestParam(value=\"id\", required=false) Integer id, Map<String, Object> map) {
	if(id != null) {
		// 模拟从数据库中获取对象
		User user = new User(1, \"Tom\", \"123456\", \"tom@atguigu.com\", 12);
		map.put(\"user\", user);
		System.out.println(\"从数据库中获取一个对象:\" + user);
	}
}

原理分析:

过程:

\"\"
@ModelAttroibute执行过程分析
版权声明

本文仅代表作者观点,不代表百度立场。
本文系作者授权百度百家发表,未经许可,不得转载。

热门文章
  • 机房智能化温湿度解决方式之POE供电以太网温湿度传感器

    机房智能化温湿度解决方式之POE供电以太网温湿度传感器
    机房智能化温湿度解决方式之POE供电以太网温湿度传感器 北京盈创力和电子科技有限公司 智能型TCP网口温湿度记录仪 北京IP网络温湿度记录仪厂家,北京盈创力和 北京智能型TCP网口温湿度记录仪IP网络温湿度记录仪是一种新型的基于TCP/IP协议双绞线以太网标准温湿度采集模块,利用它可以实现现场温度值、相对湿度值的采集,同时利用其自身的RJ45通信接口可以方便地和机房监控主机或交换机集线器进行联网。 工作于-40℃~85℃工业级带...
  • Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering

    Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering
    Problem Statement 我们考虑一个具有马尔可夫性质、非线性、非高斯的状态空间模型(State Space Model):对于一个时间序列上的观测结果{yt,t∈N}\\{ y_t , t \\in N \\}{yt​,t∈N},我们认为每个观测结果yty_tyt​的生成依赖于一个无法直接观察的隐变量xt∈{xt,t∈N}x_t \\in \\{x_t , t \\in N \\}xt​∈{xt​,t∈N},即:p(...
  • HTTP状态保持的原理

    HTTP状态保持的原理
    a)在用户登录之后,浏览器返回响应的时候会在响应中添加上cookieb)浏览器接收到cookie之后会自动保存c)当用户再次请求同一服务器中的其他网页的时候,浏览器会自动带上之前保存的cookied)服务接收到请求之后可以请 request 对象中取到cookie 判断当前用户是否登录  Http是无状态的,就是连接时数据互通,关闭后...
  • Hive 系统函数及示例

    Hive 系统函数及示例
    查看所有系统函数 show functions; 函数分类 内置函数【系统函数】 数学函数: floor、round、ceil、cos、log2等 字符串函数: length、reverse、trim、lower、get_json_object、repeat等 收集函数: size 转换函数: cast 日期函数: year、month、datediff、date、date_add等 条件函数: coalesce、case…w...
  • CSRF的原理和防范措施

    CSRF的原理和防范措施
    a)攻击原理:i.用户C访问正常网站A时进行登录,浏览器保存A的cookieii.用户C再访问攻击网站B,网站B上有某个隐藏的链接或者图片标签会自动请求网站A的URL地址,例如表单提交,传指定的参数iii.而攻击网站B在访问网站A的时候,浏览器会自动带上网站A的cookieiv.所以网站A在接收到请求之后可判断当前用户是登录状态,所以...
标签列表