1. 什么是SpringMVC参数绑定
就是将URL中的的请求参数,进行类型转换(String或其他类型),将转换后的值在赋值给Controller方法形参中,然后Controller就可以直接使用该形参。
2. 默认的参数绑定类型
- HttpServletRequest
- HttpServletResponse
- HttpSession
- Model:数据模型,主要存储要返回到客户端的数据的。功能类似于Request对象。
- ModelMap
- 演示
@RequestMapping("/Parameter")
public Stirng parameter(HttpServletRequest request,HttpServletResponse response,
HttpSession session,Model model,ModelMap modelMap) throws Exception{
request.setAttribute("requestParameter", "request类型");
response.getWriter().write("response");
session.setAttribute("sessionParameter", "session类型");
model.addAttribute("modelParameter", "model类型");
modelMap.addAttribute("modelMapParameter", "modelMap类型");
return "success";
}
3. 简单类型
- 请求URL
http://localhost:8080/springmvc/test/queryById?id=1&name=zhangsan
参数为id=1&name=zhangsan
-
Controller
注意:请求参数的key,需要和controller方法形参名称一致,注意类型是否匹配。
@RequestMapping(“queryById”)
public String queryItemById(int id,String name){}
- RequestParam
-
作用:
- 相当于request.getParameter(请求参数中的key);
- 将获取的值,绑定到该注解修饰中的参数中;
-
属性:
- value:URL请求参数中的key;
- required:true/false,表示该URL是否必须要带有该参数,默认是true;
- default:如果required设置为true,但是URL中没有指定的key,则默认取该值进行参数绑定。
4. POJO类型
- 请求参数
id=10&name=zhangsan
-
Controller
使用要求- 使用一个POJO类型的参数作为Contoller方法的参数形参,进行形参绑定。
- 请求参数的key,需要和一个POJO类型的属性名称一致。
- 如果参数的key出现这种方式
address.provinceName
,需要需要POJO类型中嵌套POJO类型的属性进行接受请求参数User#Address(address)#provinceName
。
代码
@RequestMapping("saveUser")
public String saveUser(User user,Model model) {
model.addAttribute("msg", "接收到的参数:"+user.toString());
return "success";
}
public class User {
private int id;
private String username;
private Date birthday;
private String sex;
// 演示包装POJO参数绑定
private Address address;
}
5. 日期类型
-
问题
对于字符串类型的日期参数,转换成Data的参数,会有转换类型问题。原因是因为,SpringMVC无法确定页面传入的日期格式是什么类型的,所以无法进行无法参数转换。 - 解决办法
Converter:实现类型转换
public class DateConverter implements Converter<String,Date>{
@Override
public Date convert(String source) {
// 使用Java中 SimpleDateFormat API完成日期转换
String pattern = "yyyy-MM-dd HH:mm:ss";
SimpleDateFormat dateFormat = new SimpleDateFormat(pattern );
try {
return dateFormat.parse(source);
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
}
将Converter注册到处理器适配器中
<!-- 配置注解方式处理器对应的适配器和映射器,同时还注入了很多其他的bean -->
<mvc:annotation-driven
conversion-service="conversionService" />
<!-- 配置ConversionService -->
<bean id="conversionService"
class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.springmvc.controller.converter.DateConverter"></bean>
</set>
</property>
</bean>
6. 集合或者类型
6.1 元素是简单类型的集合或数组
-
注意
- 直接使用LIst集合或者数组作为形参,List集合会报错。
- 直接使用POJO类型作为形参,并且该POJOlei类型拥有一个List集合属性或者数组属性。这种情况下List和数组都可以成功接收参数。
- 请求参数key和形参名称或者属性名称要一致。
- 请求参数
id=1&id=2&id=3
-
Controller方法
第一个和第三个是成功的,第二个不成功。
@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";
}
public class User {
// 演示批量简单类型参数接收
private List<Integer> uid = new ArrayList<>();
}
6.2 元素是POJO的类型或数组
-
注意
- 直接使用List集合或者数组作为形参,都会报错。
- 必须使用POJO类型作为形参,并且该POJO类型拥有一个List集合属性或者数组属性。这种情况下List和数组都可以成功接收参数。
- 请求参数key和属性名称要一致。
-
请求参数
POST请求
<!-- 将request请求参数,绑定到[元素是POJO类型的List集合或Map集合]参数 -->
<form action="${pageContext.request.contextPath}/user/updateUser" method="post">
<!-- 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 />
<input type="submit" value="保存">
</form>
GET请求
itemList[0].id=1&itemList[0].name=zhangsan&itemList[0].price=100&itemList[1].id=2&itemList[1].name=lisi&itemList[1].price=200
- Controller方法
@RequestMapping("updateUser")
public String updateUser(User user,Model model) {
model.addAttribute("msg", "接收到的参数:"+user.getUid());
return "success";
}
public class User {
// 将request请求参数,绑定到[元素是POJO类型的List集合]参数
private List<Item> itemList = new ArrayList<>();
}
6.3 Map集合
-
注意
- 需要使用POJO类型来接受,POJO类型中有一个Map类型的参数。
- Map类型的属性和名称,要求和请求参数[]前面的名称一致。
- Map的key要唯一,value要求是一个POJO类型。
- 请求参数
itemMap['item1'].name=zhangsan&itemMap['item1'].price=100&itemMap['item2'].name=lisi&itemMap['item2'].price=200
- POJO
public class User {
// 将request请求参数,绑定到[元素是POJO类型的Map集合]参数
private Map<String, Item> itemMap = new HashMap<>();
}
public class Item {
private Integer id;
private String name;
private Float price;
private String pic;
private Date createtime;
}
7. 文件类型
-
注意
JSP
form表单需要设置enctype=multipart/form-data
第三方依赖
commons-fileupload
commons-io
SpirngMVC的支持
MultipartResolver:解析文件类型的参数,绑定到MultipartFile类型的参数中,需要在springmvc.xml配置
MultipartFile:通过该参数,可以获取文件数据,包括文件名称和文件内容。
- 代码配置
JSP
<!-- 文件类型参数绑定 -->
<form action="${pageContext.request.contextPath}/fileupload" method="post" enctype="multipart/form-data">
图片:<input type="file" name="uploadFile" /><br />
<input type="submit" value="上传" />
</form>
springmvc.xml
<!-- 配置多部件解析器 -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 限制上传文件的大小,最大可以上传多大,单位是字节 -->
<property name="maxUploadSize" value="5000000"></property>
</bean>
Controller
@RequestMapping("fileupload")
public String findUserById(MultipartFile uploadFile,Model model) 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);
//同时需要把新的文件名更新到数据库中
}
}
model.addAttribute("msg", "文件上传成功");
return "success";
}