SpringMVC的数据绑定分几种方式,下面就其中的主要几种方式来进行分析:
1.简单数据绑定
1.1 绑定默认数据类型
SpringMVC-config.xml配置文件如下:
<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:task="http://www.springframework.org/schema/task"
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-4.3.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-4.3.xsd">
<!-- 使用包扫描 -->
<context:component-scan base-package="ltd.ourfamily.controller"></context:component-scan>
<!-- 视图解析器 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 设置前缀 -->
<property name="prefix" value="/WEB-INF/jsp/"></property>
<!-- 设置后缀 -->
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
UserController.java如下:
package ltd.ourfamily.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class UserController{
@RequestMapping(value="/userController")
public String handleRequest(HttpServletRequest request, HttpServletResponse response,Model model) throws Exception {
String id=request.getParameter("id");
System.out.println("id="+id);
return "first";
}
}
其他的文件就不用赘述了。访问地址:http://localhost:8081/SpringMVC/userController?id=1
我们在地址栏处后缀加上了参数id,然后在UserController用request.parameter()方法获得了参数值
1.2 绑定简单数据类型
修改上述的UserController.java如下:
package ltd.ourfamily.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class UserController{
@RequestMapping(value="/userController")
public String handleRequest(Integer id) throws Exception {
System.out.println("id="+id);
return "first";
}
}
这里我们用简单数据类型Integer来替换request,这样就可以直接换取到id,问题来了,如果两个参数名不一致怎么办呢?
如果地址改为http://localhost:8081/SpringMVC/userController?userId=1
SpringMVC早就考虑到这一点,我们可以用注解@RequestParam来解决这个问题:
2. 绑定POJO类型:
如果传递的参数是多个不同的类型,我们就需要考虑用POJO来作为形参传递数据:
创建一个pojo,命名为User:
修改UserController.java如下:
register.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>注册</title>
</head>
<body>
<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>
这里就很明显的看出,其使用原理和简单数据绑定很相似。但是这里需要注意:前端的请求数据的参数名必须和pojo的参数相对应!
3. 绑定包装POJO
在实际项目中,往往涉及多表联合查询,返回的数据很有可能是多表的数据,这样简单的POJO绑定就不满足我们的需求了,这样就需要我们包装POJO了。简单来说,就是一个POJO包含了另外的简单POJO,这就是包装POJO。
新建一个Orders类
重写UserController.java:
package ltd.ourfamily.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import ltd.ourfamily.po.Orders;
import ltd.ourfamily.po.User;
@Controller
public class UserController{
/**
* 跳转到注册界面
* @param id
* @return
* @throws Exception
*/
@RequestMapping("/query")
public String toRegister() {
return "register";
}
/**
* 接受用户信息
* @param id
* @return
* @throws Exception
*/
@RequestMapping(value="/findOrdersByUsername")
public String handleRequest(Orders orders) throws Exception {
Integer ordersId=orders.getOrdersId();
User user=orders.getUser();
System.out.println(ordersId);
System.out.println(user.getUsername());
return "first";
}
}
修改register.jsp
这里很明显看出,和前面的使用没什么区别,只是将POJO作为属性了而已。
4. 自定义数据绑定
4.1 使用Converter
在开发中,有些时候需要自己定义数据绑定,比如时间数据就需要从String类型转化为Data类型。
新建一个类DateConverter,作为自定义时间转换器:
package ltd.ourfamily.convert;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.core.convert.converter.Converter;
/**
* 自定义时间转化器
* @author WEI 哥
*
*/
public class DateConverter implements Converter<String, Date>{
private String dataFormat="yyyy-MM-dd HH:mm:ss";
public Date convert(String source) {
SimpleDateFormat sdf=new SimpleDateFormat(dataFormat);
try {
return sdf.parse(source);
} catch (Exception e) {
throw new IllegalArgumentException("时间格式错误,请使用格式:"+dataFormat);
}
}
}
在springmvc-config.xml中新添:
<!-- 装配自定义类型的转化器 -->
<mvc:annotation-driven conversion-service="conversionService"/>
<!-- 装配自定义转换器 -->
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="ltd.ourfamily.convert.DateConverter"/>
</set>
</property>
</bean>
修改UserController.java:
访问地址:http://localhost:8081/SpringMVC/date?date=2019-04-29 2011:11:11
console会打印内容:
可以看出,在调用这个Controller之前,就已经将String类型的数据转换为Date。
4.2 Formatter
converter和formatter都用作自定义数据绑定,不同的是,formatter的源数据必须是String,而converter则可以是任意类型。
新建DateFormatter.java:
package ltd.ourfamily.convert;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import org.springframework.format.Formatter;
public class DateFormatter implements Formatter<Date>{
String dataFormat="yyyy-MM-dd HH:mm:ss";
private SimpleDateFormat sdf;
@Override
public String print(Date date, Locale arg1) {
/*
* 返回目标对象的字符串
*/
return new SimpleDateFormat().format(date);
}
@Override
public Date parse(String source, Locale arg1) throws ParseException {
/*
* 返回解析后的目标类型
*/
sdf=new SimpleDateFormat(dataFormat);
return sdf.parse(source);
}
}
修改springmvc-config.xml
标红的部分是固定写法,运行结果同上,这里就不演示了。
5. 复杂数据绑定
5.1 绑定数组
通常,如果返回的数据类型属性一致,我们就可以考虑用数组的形式来绑定,当然使用也和前面的简单绑定一致,只需要根据类型更改参数属性即可。如果是int类型,就是int[] ids 如果是String类型,就是String[] strings 等等
5.2 绑定集合
事实上,返回类型是数组类型并不多见,最多见的是返回集合类型,尤其在请求多个同POJO类型数据,分页时。
解决方法就是创建一个包装类,包装类的属性就是目标POJO的集合,比如:
package ltd.ourfamily.vo;
import java.util.List;
import ltd.ourfamily.po.User;
public class UserVO {
private List<User> users;
public List<User> getUsers() {
return users;
}
public void setUsers(List<User> users) {
this.users = users;
}
}
然后将UserVO作为形参接受数据即可。具体的实现和前面很类似,这里就不在多说了。只是要注意前端界面的参数名(即name)必须和POJO类的参数一一对应,不然会报错的