版本:idea2020.1.1 jdk1.8 maven3.6.3
注:本文章摘自Java EE企业级应用开发教程,黑马程序员/编著,仅用于记录学习笔记,分享学习经历。
Tomcat配置参考:https://mp.csdn.net/editor/html/114296147
一、数据绑定
Spring MVC会根据客户端请求参数的不同,将请求消息中的信息以一定的方式转换并绑定到控制器类的方法参数中。这种将请求消息数据与后台方法参数建立连接的过程就是Spring MVC的数据绑定。在数据绑定过程中,Spring MVC框架会通过数据绑定组件(DataBinder)将请求参数串的内容进行类型转换,然后将转换后的赋值给控制器类中方法的形参,这样后台方法就可以正确绑定并获取客户端请求携带的参数了。
1、Spring MVC将ServletRequest对象传递给DataBinder
2、将处理方法的入参对象传递给DataBinder
3、DataBinder调用ConversionService组件进行数据类型转换、数据格式化等工作,将ServletRequest对象中的消息填充到参数对象中。
4、调用Validator组件对已经绑定了请求消息数据的参数对象进行数据合法性校验。
5、校验完成后会生成数据绑定结果BindingResult对象,Spring MVC会将BindingResult对象中的内容赋值给处理方法的相应参数。
二、简单数据绑定
数据类型 | 说明 |
---|---|
HttpServletRequest | 通过request对象获取请求信息 |
HttpServletResponse | 通过response处理响应信息 |
HttpSession | 通过session对象得到session中存储的对象 |
Model/ModelMap | Model是一个接口,ModelMap是一个接口实现,作用是将model数据填充到request域 |
创建springmvc-config.xml配置文件 ——> 创建UserController类 ——> 创建succes.jsp并发布到tomcat测试
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--指定需要扫描的包-->
<context:component-scan base-package="com.jc.controller"/>
<!--定义视图解析器-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--设置前缀-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!--设置后缀-->
<property name="suffix" value=".jsp"/>
</bean>
</beans>
@Controller
public class UserController {
@RequestMapping("/selectUser")
public String selectUser(HttpServletRequest request) {
String id = request.getParameter("id");
System.out.println("id="+id);
return "success";
}
}
<%--
Created by IntelliJ IDEA.
User: jiangchao
Date: 2021/4/12
Time: 上午 10:12
To change this template use File | Settings | File Templates.
--%>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP '' starting page</title>
<meta content="text/html;charset=UTF-8" http-equiv="Content-Type">
</head>
<body>
This is my JSP page. <br>
ok
</body>
</html>
1、绑定简单数据类型
修改UserController代码
@Controller
public class UserController {
@RequestMapping("/selectUser")
public String selectUser(Integer id) {
String id = request.getParameter("id");
System.out.println("id="+id);
return "success";
}
}
有时候前端请求中参数名和后台控制器类方法中的形参名不一样,会导致后台无法正确绑定并接受前端请求的参数。为此Spring MVC提供了@RequestParam注解进行间接数据绑定。
属性 | 说明 |
---|---|
value | name属性的别名,这里指参数的名字,即入参的请求参数名字,如value=“item_id”表示请求的参数中名字为item_id的参数的值将传入。如果只使用value属性,则可以省略value属性名。 |
name | 指定请求头绑定的名称。 |
required | 指定参数是否必须,默认是true,表示请求中一定要有响应的参数。 |
defaultValue | 默认值,表示如果请求中没有同名参数时的默认。 |
@Controller
public class UserController {
@RequestMapping("/selectUser")
public String selectUser(@RequestParam(value="user_id")Integer id) {
String id = request.getParameter("id");
System.out.println("id="+id);
return "success";
}
}
2、绑定POJO类型
创建POJO类User ——> 修改UserController ——> 添加register.jsp ——> 修改web.xml以防乱码 ——> 启动tomcat测试
public class User {
private Integer id;
private String username;
private Integer password;
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 Integer getPassword() {
return password;
}
public void setPassword(Integer password) {
this.password = password;
}
}
@Controller
public class UserController {
@RequestMapping("/selectUser")
public String selectUser(HttpServletRequest request) {
String id = request.getParameter("id");
System.out.println("id="+id);
return "success";
}
//向用户注册页面跳转
@RequestMapping("/toRegister")
public String toRegister() {
return "register";
}
//接收用户注册信息
@RequestMapping("/registerUser")
public String registerUser(User user) {
String username = user.getUsername();
Integer password = user.getPassword();
System.out.println("username="+username);
System.out.println("password="+password);
return "success";
}
}
<%--
Created by IntelliJ IDEA.
User: jiangchao
Date: 2021/4/12
Time: 上午 10:38
To change this template use File | Settings | File Templates.
--%>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP '' starting page</title>
<meta content="text/html;charset=UTF-8" http-equiv="Content-Type">
</head>
<body>
<%@ page isELIgnored="false" %>
<form action="${pageContext.request.contextPath }/registerUser" method="post">
用户名:<input type="text" name="username"/> <br/>
密码:<input type="text" name="password"/> <br/>
<input type="submit" value="注册">
</form>
</body>
</html>
<!--配置编码过滤器-->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
3、绑定包装多个POJO
创建Orders ——> 创建OrdersController ——> 创建orders.jsp ——> 运行测试
public class Orders {
private Integer ordersId;
private User user;
public Integer getOrdersId() {
return ordersId;
}
public void setOrdersId(Integer ordersId) {
this.ordersId = ordersId;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
@Controller
public class OrdersController {
//向订单查询页面跳转
@RequestMapping("/tofindOrdersWithUser")
public String tofindOrdersWithUser() {
return "orders";
}
//查询订单和用户信息
@RequestMapping("/findOrdersWithUser")
public String findOrdersWithUser(Orders orders) {
Integer orderId = orders.getOrdersId();
User user = orders.getUser();
String username = user.getUsername();
System.out.println("orderId="+orderId);
System.out.println("username="+username);
return "success";
}
}
<%--
Created by IntelliJ IDEA.
User: jiangchao
Date: 2021/4/12
Time: 上午 11:16
To change this template use File | Settings | File Templates.
--%>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP '' starting page</title>
</head>
<body>
<%@ page isELIgnored="false" %>
<form action="${pageContext.request.contextPath }/findOrdersWithUser" method="post">
订单编号:<input type="text" name="ordersId"/><br/>
所属用户:<input type="text" name="user.username"/><br/>
<input type="submit" value="查询"/>
</form>
</body>
</html>
4、自定义数据绑定
(1)Converter
Spring框架提供了一个Converter用于将一种类型的对象转换为另一种类型的对象。例如用户输入的日期形式“2017-04-03”或“2017/04/03”需要Spring将输入的日期与后台的Date进行绑定,则需要将字符串转换为日期。
创建DateConverter ——> 修改springmvc-config.xml ——> 创建DateController ——> 测试
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.core.convert.converter.Converter;
/**
* 自定义日期转换器
*/
public class DateConverter implements Converter<String, Date> {
// 定义日期格式
private String datePattern = "yyyy-MM-dd HH:mm:ss";
@Override
public Date convert(String source) {
// 格式化日期
SimpleDateFormat sdf = new SimpleDateFormat(datePattern);
try {
return sdf.parse(source);
} catch (ParseException e) {
throw new IllegalArgumentException("无效的日期格式,请使用这种格式:"+datePattern);
}
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--指定需要扫描的包-->
<context:component-scan base-package="com.jc.controller"/>
<!--定义视图解析器-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--设置前缀-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!--设置后缀-->
<property name="suffix" value=".jsp"/>
</bean>
<!--显示的装配自定义类型转换器-->
<mvc:annotation-driven conversion-service="conversionService"/>
<!--自定义类型转换器配置-->
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.jc.convert.DateConverter"/>
</set>
</property>
</bean>
</beans>
@Controller
public class DateController {
//使用自定义类型数据绑定日期数据
@RequestMapping("/customDate")
public String CustomDate(Date date) {
System.out.println("date="+date);
return "success";
}
}
(2)Formatter
与Converter作用相同,Formatter源类型必须是一个String类型,Converter可以是任意类型。
创建DateFormatter ——> 修改springmvc-config.xml
public class DateFormatter implements Formatter<Date> {
//定义日期格式
String datePattern = "yyyy-MM-dd HH:mm:ss";
//声明SimpleDateFormat对象
private SimpleDateFormat simpleDateFormat;
@Override
public Date parse(String s, Locale locale) throws ParseException {
simpleDateFormat = new SimpleDateFormat(datePattern);
return simpleDateFormat.parse(s);
}
@Override
public String print(Date date, Locale locale) {
return new SimpleDateFormat().format(date);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--指定需要扫描的包-->
<context:component-scan base-package="com.jc.controller"/>
<!--定义视图解析器-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--设置前缀-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!--设置后缀-->
<property name="suffix" value=".jsp"/>
</bean>
<!--显示的装配自定义类型转换器-->
<mvc:annotation-driven conversion-service="conversionService"/>
<!--自定义类型转换器配置2-->
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="formatters">
<set>
<bean class="com.jc.convert.DateFormatter"/>
</set>
</property>
</bean>
</beans>
三、复杂数据绑定
1、绑定数组(删除常用)
修改UserController ——> 编写user.jsp ——> 测试
@Controller
public class UserController {
@RequestMapping("/selectUser")
public String selectUser(HttpServletRequest request) {
String id = request.getParameter("id");
System.out.println("id="+id);
return "success";
}
//向用户注册页面跳转
@RequestMapping("/toRegister")
public String toRegister() {
return "register";
}
//接收用户注册信息
@RequestMapping("/registerUser")
public String registerUser(User user) {
String username = user.getUsername();
Integer password = user.getPassword();
System.out.println("username="+username);
System.out.println("password="+password);
return "success";
}
//向用户列表页面跳转
@RequestMapping("/toUser")
public String selectUsers() {
return "user";
}
//接收批量删除用户的方法
@RequestMapping("/deleteUsers")
public String deleteUsers(Integer[] ids) {
if (ids != null) {
for (Integer id:ids) {
System.out.println("删除了id为"+id+"的用户");
}
}else {
System.out.println("ids=null");
}
return "success";
}
}
<%--
Created by IntelliJ IDEA.
User: jiangchao
Date: 2021/4/12
Time: 下午 12:36
To change this template use File | Settings | File Templates.
--%>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP '' starting page</title>
</head>
<body>
<%@ page isELIgnored="false" %>
<form action="${pageContext.request.contextPath }/deleteUsers" method="post">
<table width="20%" border="1">
<tr>
<td>选择</td>
<td>用户名</td>
</tr>
<tr>
<td><input name="ids" value="1" type="checkbox"></td>
<td>tom</td>
</tr>
<tr>
<td><input name="ids" value="2" type="checkbox"></td>
<td>jack</td>
</tr>
<tr>
<td><input name="ids" value="3" type="checkbox"></td>
<td>lucy</td>
</tr>
</table>
<input type="submit" value="删除"/>
</form>
</body>
</html>
2、绑定集合(修改常用)
编写UserVO类 ——> 修改UserController ——> 编写user_edit.jsp ——> 测试
//用户包装类
public class UserVO {
private List<User> userList;
public List<User> getUserList() {
return userList;
}
public void setUserList(List<User> userList) {
this.userList = userList;
}
}
//向用户批量修改页面跳转
@RequestMapping("/toUserEdit")
public String toUserEdit() {
return "user_edit";
}
//接收批量修改用户的方法
@RequestMapping("/editUsers")
public String editUsers(UserVO userList) {
//将所有用户数据封装到集合中
List<User> users = userList.getUserList();
//循环输出所有用户信息
for (User user:users) {
//如果接收的用户id不为空,则表示修改成功
if (user.getId() != null) {
System.out.println("修改了id为"+user.getId()+"的用户名为"+user.getUsername());
}
}
return "success";
}
<%--
Created by IntelliJ IDEA.
User: jiangchao
Date: 2021/4/12
Time: 下午 1:01
To change this template use File | Settings | File Templates.
--%>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP '' starting page</title>
</head>
<body>
<%@ page isELIgnored="false" %>
<form action="${pageContext.request.contextPath }/editUsers" method="post" id="formid">
<table width="30%" border="1">
<tr>
<td>选择</td>
<td>用户名</td>
</tr>
<tr>
<td><input name="userList[0].id" value="1" type="checkbox"></td>
<td><input name="userList[0].username" value="tom" type="text"></td>
</tr>
<tr>
<td><input name="userList[1].id" value="2" type="checkbox"></td>
<td><input name="userList[1].username" value="jack" type="text"></td>
</tr>
</table>
<input type="submit" value="修改"/>
</form>
</body>
</html>