文章目录
- 参数绑定
- 默认支持的参数类型
- 参数绑定使用要求
- 简单类型
- RequestParam注解
- 绑定POJO类型
- 绑定集合或者数组类型
- 参数绑定示例
- JSP代码
- Controller代码
- PO代码
- 自定义日期参数绑定
- Converter代码
- Converter配置
- 文件类型参数绑定
- 加入依赖包
- 上传页面
- 配置Multipart解析器
- Controller类代码
参数绑定
- 什么是参数绑定
就是将请求参数串中的value值获取到之后,再进行类型转换,然后将转换后的值赋值给Controller
类中方法的形参,这个过程就是参数绑定。
总结参数绑定需要两步:
–类型转换(请求中的String类型值—>Controller各种数据类型的方法形参)
–赋值操作,将转换之后的值赋值给Controller方法形参
- 请求参数格式
默认是key/value格式,比如: http://XXXXX?id=1&type=301
- 请求参数值的数据类型
都是String类型的各种值
- 请求参数值要绑定的目标类型
Controller类中的方法参数,比如简单类型、POJO类型、集合类型等
- SpringMVC内置的参数解析组件
默认内置了24种参数解析组件(ArgumentResolver)
默认支持的参数类型
Controller方法形参中可以随时添加如下类型的参数(Servlet API支持),处理适配器会自动识别并进行赋值
- HttpServletRequest
通过 request 对象获取请求信息
- HttpServletResponse
通过 response 处理响应信息
- HttpSession
通过 session 对象得到 session 中存放的对象
- InputStream、OutputStream
- Reader、Writer
- Model/ModelMap
ModelMap 继承自 LinkedHashMap ,Model是一个接口,它们的底层实现都是同一个类
( BindingAwareModelMap ),作用就是向页面传递数据,相当于 Request 的作用,如下:
model.addAttribute("msg", “测试springmvc”);
参数绑定使用要求
简单类型
- 直接绑定
http请求参数的【key】和controller方法的【形参名称】一致
- 注解绑定
请求参数的【key】和controller方法的【形参名称】不一致时,需要使用【@RequestParam】注解才能将请求参数绑定成功。
RequestParam注解
- value:
参数名字,即入参的请求参数名字,如value=“itemid”表示请求的参数中的名字为itemid的参数的值将传入
- required:
是否必须,默认是true,表示请求中一定要有相应的参数,否则将报;
TTP Status 400 - Required Integer parameter ‘XXXX’ is not present
- defaultValue:
默认值,表示如果请求中没有同名参数时的默认值
绑定POJO类型
要求表单中【参数名称】和Controller方法中的【POJO形参的属性名称】保持一致。
绑定集合或者数组类型
- 简单类型数组
通过HTTP请求批量传递简单类型数据的情况,Controller方法中可以用String[]或者pojo的String[]属性接收(两种方式任选其一),但是不能使用List集合接收。
- POJO类型集合或者数组
批量传递的请求参数,最终要使用List来接收,那么这个List必须放在另一个POJO类中。
参数绑定示例
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>参数绑定演示demo</title>
</head>
<body>
<!-- request请求的内容类型主要分为:K/V类型、Multipart类型、JSON类型 -->
<!-- 将request请求参数,绑定到简单类型(基本类型和String类型)方法参数 -->
<!-- 直接绑定 -->
<a href="${pageContext.request.contextPath}/user/findUserById?
id=1&name=bingbing">查询用户1</a>
<!-- @RequestParam注解绑定 -->
<a href="${pageContext.request.contextPath}/user/findUserById2?uid=1">查询用
户2</a>
<!-- 将request请求参数,绑定到POJO类型(简单POJO和包装POJO的)方法参数 -->
<form action="${pageContext.request.contextPath}/user/saveUser"
method="post">
用户名称:<input type="text" name="username"><br />
用户性别:<input type="text" name="sex"><br />
所属省份:<input type="text" name="address.provinceName"><br />
所属城市:<input type="text" name="address.cityName"><br />
<input type="submit" value="保存">
</form>
<!-- 将request请求参数,绑定到[元素是简单类型的集合或数组]参数 -->
<!-- 使用数组接收 -->
<a href="${pageContext.request.contextPath}/user/findUserByIds?
id=1&id=2&id=3">根据ID批量删除用户</a>
<!-- 使用List接收(错误示例) -->
<a href="${pageContext.request.contextPath}/user/findUserByIds2?
id=1&id=2&id=3">根据ID批量删除用户</a>
<!-- 使用Bean的List属性接收 -->
<a href="${pageContext.request.contextPath}/user/findUserByIds3?
uid=1&uid=2&uid=3">根据ID批量删除用户</a>
<!-- 将request请求参数,绑定到[元素是POJO类型的List集合或Map集合]参数 -->
<form action="${pageContext.request.contextPath}/user/updateUser"
method="post">
用户名称:<input type="text" name="username"><br />
用户性别:<input type="text" name="sex"><br />
<!-- itemList[集合下标]:集合下标必须从0开始 -->
<!-- 辅助理解:先将name属性封装到一个Item对象中,再将该Item对象放入itemList集合的
指定下标处 -->
购买商品1名称:<input type="text" name="itemList[0].name"><br />
购买商品1价格:<input type="text" name="itemList[0].price"><br />
购买商品2名称:<input type="text" name="itemList[1].name"><br />
购买商品2价格:<input type="text" name="itemList[1].price"><br />
<!-- itemMap['item3']:其中的item3、item4就是Map集合的key -->
<!-- 辅助理解:先将name属性封装到一个Item对象中,再将该Item对象作为value放入
itemMap集合的指定key处 -->
购买商品3名称:<input type="text" name="itemMap['item3'].name"><br />
购买商品3价格:<input type="text" name="itemMap['item3'].price"><br />
购买商品4名称:<input type="text" name="itemMap['item4'].name"><br />
购买商品4价格:<input type="text" name="itemMap['item4'].price"><br />
<input type="submit" value="保存">
</form>
<!-- 将request请求参数,绑定到Date类型方法参数 -->
<!-- 请求参数是:【年月日】 格式 -->
<a href="${pageContext.request.contextPath}/user/deleteUser?birthday=2018-
01-01">根据日期删除用户(String)</a>
<!-- 请求参数是:【年月日 时分秒】 格式 -->
<a href="${pageContext.request.contextPath}/user/deleteUser2?birthday=2018-
01-01 12:10:33">根据日期删除用户(Date)</a>
<!-- 文件类型参数绑定 -->
<form action="${pageContext.request.contextPath}/fileupload" method="post"
enctype="multipart/form-data">
图片:<input type="file" name="uploadFile" /><br />
<input type="submit" value="上传" />
</form>
</body>
</html>
Controller代码
/**
* 用来学习参数绑定
*
*/
@RequestMapping("user")
@Controller
public class UserController {
@RequestMapping("findUserById")
public String findUserById(Integer id,Model model,HttpServletRequest
request) {
model.addAttribute("msg", "直接参数绑定接收到的参数:"+id);
model.addAttribute("msg", "通过Request getParameter参数接收到的参
数:"+request.getParameter("id"));
return "success";
}
// @RequestParam:可以理解为request.getParameter("参数key")
@RequestMapping("findUserById2")
public String findUserById2(@RequestParam("uid") Integer id,Model model) {
model.addAttribute("msg", "接收到的参数:"+id);
return "success";
}
@RequestMapping("saveUser")
public String saveUser(User user,Model model) {
model.addAttribute("msg", "接收到的参数:"+user.toString());
return "success";
}
@RequestMapping("deleteUser")
public String deleteUser(String birthday,Model model) {
model.addAttribute("msg", "接收到的参数:"+birthday);
return "success";
}
@RequestMapping("deleteUser2")
public String deleteUser2(Date birthday,Model model) {
model.addAttribute("msg", "接收到的参数:"+birthday);
return "success";
}
@RequestMapping("findUserByIds")
public String findUserByIds(Integer[] id,Model model) {
model.addAttribute("msg", "接收到的参数:"+id);
return "success";
}
@RequestMapping("findUserByIds2")
public String findUserByIds2(List<Integer> id,Model model) {
model.addAttribute("msg", "接收到的参数:"+id);
return "success";
}
@RequestMapping("findUserByIds3")
public String findUserByIds3(User user,Model model) {
model.addAttribute("msg", "接收到的参数:"+user.getUid());
return "success";
}
@RequestMapping("updateUser")
public String updateUser(User user,Model model) {
model.addAttribute("msg", "接收到的参数:"+user.getUid());
return "success";
}
}
PO代码
public class User {
private int id;
private String username;
private Date birthday;
private String sex;
// 演示包装POJO参数绑定
private Address address;
// 演示批量简单类型参数接收
private List<Integer> uid = new ArrayList<>();
// 将request请求参数,绑定到[元素是POJO类型的List集合]参数
private List<Item> itemList = new ArrayList<>();
// 将request请求参数,绑定到[元素是POJO类型的Map集合]参数
private Map<String, Item> itemMap = new HashMap<>();
//setter/getter方法
}
自定义日期参数绑定
对于springmvc无法解析的参数绑定类型,比如[年月日时分秒格式的日期]绑定到Date类型会报错,此时需
要自定义[参数转换器]进行参数绑定。
Converter代码
public class DateConverter implements Converter<String, Date> {
@Override
public Date convert(String source) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
try {
return simpleDateFormat.parse(source);
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
}
Converter配置
<!-- 加载注解驱动 -->
<mvc:annotation-driven conversion-service="conversionService"/>
<!-- 转换器配置 -->
<bean id="conversionService"
class="org.springframework.format.support.FormattingConversionServiceFactoryBean
">
<property name="converters">
<set>
<bean class="com.ssm.controller.converter.DateConverter"/>
</set>
</property>
</bean>
文件类型参数绑定
SpringMVC 文件上传的实现,是由 commons-fileupload 这个第三方jar包实现的。
加入依赖包
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
上传页面
JSP中的form表单需要指定enctype=”multipart/form-data”
配置Multipart解析器
在 springmvc.xml 中配置 multipart 类型解析器:
<!-- multipart类型解析器,文件上传 -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 上传文件的最大尺寸 5M-->
<property name="maxUploadSize" value="5242880"/>
</bean>
Controller类代码
@RequestMapping("fileupload")
public String findUserById(MultipartFile uploadFile) throws Exception {
// 编写文件上传逻辑(mvc模式和三层结构模式)
// 三层模式:表现层(controller、action)、业务层(service、biz)、持久层(dao、
mapper)
// MVC模式主要就是来解决表现层的问题的(原始的表现层是使用Servlet编写,即编写业务逻
辑,又编写视图展示)
if (uploadFile != null) {
System.out.println(uploadFile.getOriginalFilename());
// 原始图片名称
String originalFilename = uploadFile.getOriginalFilename();
// 如果没有图片名称,则上传不成功
if (originalFilename != null && originalFilename.length() > 0) {
// 存放图片的物理路径
String picPath = "E:\\";
// 获取上传文件的扩展名
String extName =
originalFilename.substring(originalFilename.lastIndexOf("."));
// 新文件的名称
String newFileName = UUID.randomUUID() + extName;
// 新的文件
File newFile = new File(picPath + newFileName);
// 把上传的文件保存成一个新的文件
uploadFile.transferTo(newFile);
// 同时需要把新的文件名更新到数据库中
}
}
return "文件上传成功";
}