本文是我在学习Java EE过程中记录学习的点点滴滴,仅仅为了学完之后巩固一下,日后忘记了也可以方便快速的复习。
Spring MVC数据绑定和响应
前言
今天主要学习的是关于spring中在jsp页面与controller层之间传参的事儿,根据在jsp页面中传过来的数据的不同在controller中所使用的返回值也有所不同。
一、简单数据绑定
1.1、默认数据绑定
HttpServletRequest:获取请求信息
HttpServletResponse:处理响应信息
在controller中一般这样写来接受参数,将参数封装在HttpServletRequest对象request中。
controller类:
@RequestMapping(value="json.do")
protected void json(HttpServletRequest request){
//获取值
String useid=request.getparameter("userid");
System.out.println("userid="+userid);
}
1.2、简单数据类型绑定
简单数据类型绑定就是指Java中基本类型的数据绑定。
在SpringMVC进行简单数据类型的绑定只需要客户端请求的参数的名称与处理器的形参名称一致即可,请求参数会自动映射并匹配到处理器的形参完成数据绑定。
controller类:
@RequestMapping(value="add.do")
protected ModelAndView orderadd(String sno){
//获取值
Map<String,Object> model=new HashMap<String,Object>();
model.put("sno",sno);
ModelAndView md=new ModelAndView("WEB-INF/view/addstudent.jsp",model);
return md;
}
上面的orderadd的形参sno要和jsp页面表单中的元素的name值要一样(这里传的是单选框radio的值,所以单选框的name也为sno)。
1.3、POJO绑定
jsp页面:
package com.mvc.entity;
public class Student {
String sno;
String sname;
String sex;
String sbirthday;
String sclass;
public Student() {
}
public Student(String sno,String sname,String sex,String sbirthday,String sclass) {
this.sno=sno;
this.sname=sname;
this.sex=sex;
this.sbirthday=sbirthday;
this.sclass=sclass;
}
public String toString() {
return sno+" "+sname+" "+sex+" "+sbirthday+" "+sclass;
}
public String getSno() {
return sno;
}
public void setSno(String sno) {
this.sno = sno;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getSbirthday() {
return sbirthday;
}
public void setSbirthday(String sbirthday) {
this.sbirthday = sbirthday;
}
public String getSclass() {
return sclass;
}
public void setSclass(String sclass) {
this.sclass = sclass;
}
}
controller类:
@RequestMapping(value="pojo.do")
protected String pojo(Student s) {
service.addstudent(s);
return "redirect:studentlist.do";
}
student.java:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>学生信息</title>
</head>
<body>
<h2>添加学生信息</h2>
<form action="pojo.do">
<table>
<tr>
<td>学号:</td>
<td><input type="text" name="sno"></td>
</tr>
<tr>
<td>姓名:</td>
<td><input type="text" name="sname"></td>
</tr>
<tr>
<td>性别:</td>
<td><input type="text" name="sex"></td>
</tr>
<tr>
<td>出生日期:</td>
<td><input type="text" name="sbirthday"></td>
</tr>
<tr>
<td>班级:</td>
<td><input type="text" name="sclass"></td>
</tr>
<tr>
<td colspan="2" align="center" ><button type="submit">添加</button></td>
</tr>
</table>
</form>
</body>
</html>
这种方法其实就是将jsp页面中要传的多个不同类型的参数封装到student类中(换种说法就是用Student类来接收参数)当然重点是:jsp页面的元素名称name值要和student类里定义的属性名要一模一样
,然后在controller中的参数就时student类的对象,该对象具有你要从jsp页面要传的所有数据。这样客户端发送请求时,请求数据会自动绑定到处理器形参POJO对象(Student s)中。
二、复杂数据绑定
实际开发中我们经常会遇到一些比较复杂的数据绑定,例如数组的绑定,集合的绑定,复杂POJO的绑定和json数据的绑定。
2.1、数组的绑定
实际应用中我们会遇到客户端请求需要传递多个同名参数
到服务器的情况,这时我们可以使用数组来接受客户端的请求参数,完成数据绑定。
controller类: 参数为String[ ] 数组类型的cid
@RequestMapping(value="delcourse.do")
protected String deletecourse(String[] cid) {
//获取值
service.delcourse(cid);
return "redirect:courselist.do";
}
jsp页面: 多选框checkbox的name为cid
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Insert title here</title>
<script type="text/javascript">
function delcourse(){
//获取表单
thisForm= document.forms[0];
//动态修改action属性
thisForm.action="delcourse.do";
}
</script>
</head>
<body>
<form action="addcourse.do">
<table border="3" width="50%">
<tr>
<th>选择</th>
<th>课程号</th>
<th>课程名称</th>
<th>学分</th>
<th>授课教师</th>
</tr>
<c:forEach items="${courselist}" var="c">
<tr>
<td><input type="checkbox" name="cid" value="${c.cno}"></td>
<td>${
c.cno}</td>
<td>${
c.cname}</td>
<td>${
c.credit}</td>
<td>${
c.tno}</td>
</tr>
</c:forEach>
<tr>
<td colspan="2" align="center"><button type="submit">添加</button></td>
<td colspan="2" align="center"><button type="submit" onclick="delcourse()">删除</button></td>
</tr>
</table>
</form>
</body>
</html>
客户端请求的参数名称要和controller中方法形参要一样。
2.2、集合绑定
除了使用数组来绑定多个同名的请求参数,还可以使用集合进行多参数的绑定。集合中存储简单数据类型时,数据的绑定规则与数组的绑定规则相似,客户端请求的参数名称要和controller中方法形参要一样。不同的是,使用集合绑定时,处理器的形参名称要使用@RequestParam注解标注。
controller类: @RequestParam(“cid”)中的表单元素名(cid为checkbox的name名)要和形参名一样。
@RequestMapping(value="delcourse.do")
protected String deletecourse(@RequestParam("cid") List<String> cid) {
//获取值
service.delcourse(cid);
return "redirect:courselist.do";
}
2.3、复杂POJO绑定
所谓的复杂POJO,就是POJO属性的类型不仅仅包含简单数据类型,还包括对象类型,List类型和Map类型等其他引用类型。
2.3.1、属性为对象类型的数据绑定(传递的是一个类的一个对象)
order类:
public class order {
String orderId;
}
customer类: 这个类里面有一个Order类的属性order
public class customer {
private Order order;
private String username;
private String password;
controller类:
@RequestMapping(value="findorder.do")
protected void json1(Customer c) {
String username=c.getUsername();
string orderId=c.getOrder().getOrderId();
System.out.println("username="+username+"orderId="+orderId);
}
jsp页面: 所属用户是传给customer类的username,所有name也为username,而订单编号是传给customer类里的order类的orderId属性,所有它的name要和order类里的orderId一模一样,因此name为order.orderId,即要与最底层的你要传的属性name一模一样。
<form action="findorder.do">
<table border="3" width="50%">
所属用户:<input type="text" name="username">
订单编号:<input type="text" name="order.orderId">
<button type="submit">查询</button>
</table>
</form>
2.3.2、属性为List类型的数据绑定(传递的是一个类的多个对象)
order类:
public class order {
String orderId;
}
customer类: 这个类里面有一个List<Order>类的属性order
public class customer {
private List<Order> orders;
private List<String> address;
private String username;
private String password;
controller类:
@RequestMapping(value="findorder.do")
protected void json1(Customer c) {
String username=c.getUsername();
List<Order> orderIds=c.getOrder().getOrderId();
System.out.println("username="+username+"orderId="+orderId);
}
jsp页面:
这里的jsp页面和上面的form表单元素的name命名规则一样,要与最底层的属性名一样,即order中的属性。但是此处需要传的是多个order类的对象,即多几个order类的属性。例如多个order类的orderId。
①如果List的泛型为简单类型,则客户端参数名称必须和与POJO类中List属性所属类中的属性名称保持一致。例如表单提交时,name为address的元素的数据将绑定到customer类的address属性中。
②如果List的泛型参数为对象类型,则客户端参数名称必须与POJO类层次结构名称保持一致,并使用数组格式描述对象在List 中的位置,即客户端参数名称必须与最终绑定在List中的某个对象的某个属性的名称保持一致(即为我上面所讲的要和最底层的类的属性名名称一致)。
2.3.3、属性为Map类型的数据绑定(即键值对,可绑多个不同类型的值)
除了使用对象类型、List类型绑定多个数据外,还可以使用Map数据类型来完成多个参数的数据绑定。
order类: Product是一个类,类里有proId ,proname两个属性
public class order {
String orderId;
HashMap<String,Product> productInfo;
}
controller类:
@RequestMapping(value="orderInfo.do")
protected void getOrderInfo(Order order) {
//获取数据
String orderId=order.getOrderId();
HashMap<String,Product> orderInfo=order.getOrderInfo();
Set<String> keys=orderInfo.keySet();
//输出数据
System.out.println("订单Id"+orderId);
System.out.println("订单商品信息:");
for(String key:keys){
//此处获取的是相应的key的value
Product product=orderInfo.get(key);
String proId=product.getProId();
String proName=product.getProName();
System.out.println(key+"类~"+"商品id:"+proId+",商品名称:"proName);
}
}
jsp页面:
<form action="orderInfo.do">
<table border="3" width="50%">
<tr>
订单id:<input type="checkbox" name="orderId" value="1">
</tr>
<tr>
<td>商品Id</td>
<td>商品名称</td>
</tr>
<tr>
<td><input type="text" name="productInfo['生鲜'].proId" value="1"></td>
<td><input type="text" name="productInfo['生鲜'].proName" value="三文鱼"></td>
</tr>
<tr>
<td><input type="text" name="productInfo['酒水'].proId" value="2"></td>
<td><input type="text" name="productInfo['酒水'].proName" value="嘉多宝"></td>
</tr>
</table>
<input type="button" value="提交">
</form>
在对复杂POJO数据进行绑定时,如果数据绑定到Map类型的属性,客户端请求的参数名称(form表单元素名称)必须与POJO类的层次结构保持一致,并使用键值的映射格式描述对象在Map中位置,即客户端参数名称必须要与要绑定的Map中的具体对象的具体属性的名称保持一致,例如表上述单提交时,name为productInfo['生鲜'].proId的元素数据将被绑定到order类productInfo集合中键为“生鲜”的对象的属性中,且属性名称为proId