前言
在前面的文章中我们对SpringMVC的架构和组件都有了一定的了解,今天我们来了解一下SpringMVC中的参数绑定问题。
正文
绑定普通参数
在前面的Demo中,我们写了这样一个方法:
@RequestMapping("/login")
public ModelAndView login(String username, String password) {
ModelAndView model = new ModelAndView();
model.addObject("data", "登录成功");
model.setViewName("/WEB-INF/jsp/login.jsp");
return model;
}
在这个方法中,方法的形参是String类型的username和password,这也对应jsp中input标签中的name属性。所以只要方法形参中的属性名和表单中标签的属性名一直,SpringMVC就可以自动的将页面中的参数放入方法的形参中。
SpringMVC默认支持的参数类型有以下几种:
- HttpServletRequest
- HttpServletResponse
- HttpSession
- Model
- ModelMap
以上五种参数类型,可以直接在处理器的形参中添加,并且会自动的识别赋值,使用起来很方便。
下面演示了用model接受参数的方式:
@RequestMapping("/login")
public ModelAndView login(String username, String password) {
ModelAndView model = new ModelAndView();
model.addObject("data", "登录成功");
model.setViewName("/WEB-INF/jsp/login.jsp");
return model;
}
在jsp页面中取的时候需要用${}来获得参数值
<body>
<h1>测试页面</h1>
<form action="">
账号:<input type="text" name="username">
密码:<input type="password" name="password">
<h3>${data}</h3>
</form>
</body>
启动项目,正常访问:
controller方法的参数类型推荐使用包装类,因为基础类型的参数不能为null,对于布尔型的参数,请求的参数值为true或者false。
比如方法:public String editItem(Model model,Integer id,Boolean status)
则请求url:http://localhost:8080/xxx.action?id=2&status=false
绑定pojo类型参数
如果我们页面中的username和password对应的是服务端的一个普通的pojo类,该如何接受呢?
首先,pojo的属性要和页面中的属性名一直,并且有set/get方法。
package com.xiaojian.springmvc.pojo;
public class User {
private String username;
private String password;
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;
}
}
下面是对应的controller中的方法:
@RequestMapping("/login")
public ModelAndView login(User user, ModelAndView model) {
System.out.println(user.getUsername());
System.out.println(user.getPassword());
model.addObject("data", "登录成功");
model.setViewName("/WEB-INF/jsp/login.jsp");
return model;
}
页面jsp设置一下提交按钮:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!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=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<h1>测试页面</h1>
<form action="${pageContext.request.contextPath }/login.action">
账号:<input type="text" name="username">
密码:<input type="password" name="password">
<h3>${data}</h3>
<input type="submit" value="登录">
</form>
</body>
</html>
运行项目,由于第一次访问的时候没人任何参数,所以控制台打印的是null,第二次则打印出对应的参数值:
注意:提交的表单中不要有日期类型的数据,否则会报400错误。如果想提交日期类型的数据需要用到后面的自定义参数绑定的内容。
自定义参数的绑定
先在我们修改一下jsp页面,加入一个日期类型的数据:
<h1>测试页面</h1>
<form action="${pageContext.request.contextPath }/login.action">
账号:<input type="text" name="username">
密码:<input type="password" name="password">
<br/>
自定义日期格式数据测试:
<input type="text" name="texttime" value="<fmt:formatDate value='${texttime}' pattern='yyyy-MM-dd HH:mm:ss'/>"/>
<h3>${data}</h3>
<input type="submit" value="登录">
</form>
现在表单在提交时,会将texttime属性提交,要想在controller中接受这个属性,必须先在配置文件中自定义一个Converter。
<?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:dubbo="http://code.alibabatech.com/schema/dubbo" 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.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<!-- 配置包扫描,扫描指定包下面的类 加载到spring容器中 -->
<context:component-scan base-package="com.xiaojian.springmvc.controller"/>
<mvc:annotation-driven conversion-service="conversionService"/>
<!-- <mvc:annotation-driven/> -->
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.xiaojian.springmvc.converter.DateConverter"/>
</set>
</property>
</bean>
</beans>
然后创建一个自定义的Converter,实现对应spring的converter接口:
package com.xiaojian.springmvc.converter;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.core.convert.converter.Converter;
public class DateConverter implements Converter<String, Date> {
public Date convert(String source) {
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return sdf.parse(source);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
需要注意的是,Converter
@RequestMapping("/login")
public ModelAndView login(User user, ModelAndView model, Date texttime) {
System.out.println(user.getUsername());
System.out.println(user.getPassword());
System.out.println(texttime);
model.addObject("data", "登录成功");
model.addObject("texttime", new Date());
model.setViewName("/WEB-INF/jsp/login.jsp");
return model;
}
控制台打印结果如下:
对应的,如果你要使用pojo来接受表单参数,且表单中包含一个日期格式的数据,那么你的pojo类中必须有一个对应日期的属性,属性名和表单中的name属性一致,这样子SpringMVC会自动帮我们将对应的参数绑定到pojo。
绑定数组
对于数组,页面中在使用checkbox类型的input提交的数据,我们在controller的方法中可以用对应类型的数组来接收;如果该数组属性是对应pojo的一个属性,同样可以定义pojo的属性为该数组,也能够接收到对应的数据。
接受List数据类型
如果页面中提交的参数是List类型的数据,每一个List的元素都是一个pojo,这个时候接收数据不能再controller中方法的形参上来接收,必须将该List元素定义为某个pojo的属性才能正确接收到数据,这一点需要注意。
总结
关于SpringMVC的参数绑定,说到这里也都基本上告一段落,在实际项目的中,根据实际的业务需求,选择合适的参数类型能很大程度上简化我们的开发。在后面的博文中,我们将对SpringMVC的中经常使用的注解做个总结和归纳。