SpringMVC教程之ModelAttribute注解

一、前言

我们先来了解一个场景: 要求修改数据库中的某条记录的部分,部分值不能给修改。例如:数据库表有3个字段,1个字段不能被修改,而更新的时候,表单提交的只有两个参数,实体中只有两个属性被赋值,其中一个属性是null.用平常的update更新,会有一个字段被置空。

这种情况,传统解决方式:

  • 使用隐藏域但是隐藏域有两个问题,问题一:如果是比较敏感的字段(比如密码)不能放隐藏域,另一个问题就是字段较多的情况,使用隐藏域比较麻烦
  • 更新之前,先做查询操作把表单未提交的值通过查询获取。这样的方法也比较麻烦

SpringMVC为我们提供了一个高效的功能,使用ModelAttribute注解。在表单对对应属性赋值之前,实体对象不是new出来的,而是从数据库查询封装后的,然后表单提交过来将对应的属性赋值到这个对象上,只赋值了两个(这两个是从表单过来的),还有一个是本来数据库查询出来就有的,最后我们拿着这个重新赋值之后的对象去做update操作,就是ModelAttribute注解的使用的应用场景。

二、案例

♦新建一个JSP测试页面

模拟修改操作  

  • 原始数据为: 1, Queen, 123456,queen@163.com,27 
  • 密码不能被修改
  • 表单回显, 模拟操作直接在表单填写对应的属性值 
<%@ 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>测试页面</title>
</head>
<body>
	<form action="user/testModelAttribute" method="POST">
		<input type="hidden" name="id" value="1"/>
		用户名: <input type="text" name="userName" value="Queen"/>
		<br>
		邮箱: <input type="text" name="email" value="queen@163.com"/>
		<br>
		年龄: <input type="text" name="age" value="27"/>
		<br>
		<input type="submit" value="提交"/>
	</form>
</body>
</html>

运行起来之后界面如下:

SpringMVC教程之ModelAttribute注解的照片 - 1

♦User实体类

/**
 * @author queen
 * @since 2017-11-7
 */
public class User {
	private Integer id;
	//用户名
	private String userName;
	//密码
	private String password;
	//邮箱
	private String email;
	//年龄
	private Integer age;
	
        public User(){}
	public User(Integer id, String userName, String password, String email,
			Integer age) {
		this.id = id;
		this.userName = userName;
		this.password = password;
		this.email = email;
		this.age = age;
	}
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	@Override
	public String toString() {
		return "User [id=" + id + ", userName=" + userName + ", password="
				+ password + ", email=" + email + ", age=" + age + "]";
	}
	
}

♦编写测试类

/**
 * @author queen
 * @since 2017-11-7
 */
@RequestMapping("/user")
@Controller
public class UserHandler {
	@RequestMapping(value = "/testModelAttribute", method = RequestMethod.POST)
	public String testModelAttribute(User user) {
		System.out.println("修改:" + user);
		return "success";
	}
}

运行结果如下:

SpringMVC教程之ModelAttribute注解的照片 - 3

从上图:我们发现password为空,但是我们说了模拟的原始数据密码是123456.显然这样做是不行的,我们上面也说了使用原始的方式加隐藏域也可以实现,但是像密码这种敏感的数据最好不要做隐藏域,这时就轮到ModelAttribute出场了。

补上一段方法如下:

SpringMVC教程之ModelAttribute注解的照片 - 5

再次运行一下,运行结果如下:

SpringMVC教程之ModelAttribute注解的照片 - 7

ModelAttribute注解的最典型使用:在修改数据之前先查询数据库,然后表单值赋值给数据库获取到的对象的对应属性,没赋值的字段(这里的密码就是没有被赋值的)是从数据库取到的原始值,这样我们就不会丢失没有被赋值的字段的值。

我们可以Debug一下代码看一下赋值的过程

SpringMVC教程之ModelAttribute注解的照片 - 9

F8进入目标方法,查看此时User的值

SpringMVC教程之ModelAttribute注解的照片 - 11

表单上修改后的值赋给了user对象,password值没有丢失。这里的user是从数据库查询出来的,而不是new出来的。

下节我们将从源码角度看看这两段方法之间,数据是如何转换的。

至此,我们关于SpringMVC教程之ModelAttribute注解介绍完毕。想要了解更多关于SpringMVC开发的教程,请参考http://www.marsitman.com/springmvc
博客地址:http://www.marsitman.com/springmvc/springmvc-model-attribute.html
版权声明:本文为博主原创文章,允许转载,但转载必须标明出处。

 

 

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!



点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注