Spring MVC数据绑定和响应——复杂数据绑定(三)复杂POJO绑定

一、复杂POJO数组绑定的使用场景

使用简单POJO类型已经可以完成多数的数据绑定,但有时客户端请求中传递的参数比较复杂。例如,在用户查询订单时,页面传递的参数可能包括订单编号、用户名称等信息,这就包含了订单和用户两个对象的信息。如果将订单和用户的所有查询条件都封装在一个简单POJO中,显然会比较混乱,这时可以考虑使用复杂POJO类型的数据绑定。

二、复杂POJO的3种属性的类型

所谓的复杂POJO,就是POJO属性的类型不止包含简单数据类型,还包含对象类型、List类型和Map类型等其他引用类型。接下来分别对复杂POJO中属性为对象类型的数据绑定、属性为List类型的数据绑定和属性为Map类型的数据绑定进行讲解。

三、属性为对象类型的数据绑定

下面通过一个获取用户订单信息的案例,演示复杂POJO中对象类型的数据绑定,案例具体实现步骤如下。

1、创建一个订单类Order,用于封装订单信息,Order类的具体代码如下所示。

java 复制代码
public class Order {
    private String orderId;            //订单id
    public String getOrderId() {
        return orderId;
    }

    public void setOrderId(String orderId) {
        this.orderId = orderId;
    }
}

2、修改User.java类,在User类中新增Order类型的属性order,并定义相应的getter和setter方法。修改后User类的具体代码如下所示。

java 复制代码
public class User{
    private String username;        //用户名
    private String password;        //用户密码
    private Order order;

    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;
    }

    public Order getOrder() {
        return order;
    }

    public void setOrder(Order order) {
        this.order = order;
    }
}

3、在UserController.java类中定义方法findOrderWithUser( ),用于获取客户端请求中的User信息,findOrderWithUser( )方法的具体代码如下所示。

java 复制代码
@RequestMapping("/findOrderWithUser")
public void findOrderWithUser(User user) {
	String username = user.getUsername();
	String orderId = user.getOrder().getOrderId();
	System.out.println("username="+username+",
	orderId="+orderId);
}

4、创建一个订单信息文件order.jsp,在order.jsp文件中创建一个表单,表单中包含用户名和订单编号。表单提交时将用户名和订单编号信息发送到处理器。order.jsp的具体代码如下所示。

html 复制代码
<%@ page language="java" contentType="text/html; 
	charset=UTF-8" pageEncoding="UTF-8"%>
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>订单信息</title></head><body><form 
   action="${pageContext.request.contextPath }/findOrderWithUser"method="post">
	所属用户:<input type="text" name="username" /><br /> 
	订单编号:<input type="text" name="order.orderId" /><br /> 
	<input type="submit" value="查询" />
</form>	</body></html> 

四、复杂POJO数组绑定的格式

在复杂POJO数据绑定时,如果数据需要绑定到POJO属性对象的属性中,客户端请求的参数名(本例中指form表单内各元素name的属性值)的格式必须为"属性对象名称.属性",其中"属性对象名称"要和POJO的属性对象名称一致,"属性"要和属性对象所属类的属性一致。

5、启动chapter12项目,在浏览器中访问订单页面order.jsp,访问地址为http://localhost:8080/chapter12/order.jsp。在所示的表单中,填写所属用户为"享受",订单编号为"9527",单击"查询"按钮,控制台打印信息如下图所示。

java 复制代码
username=享受,oederId=9527

五、属性为List类型的数据绑定

接下来通过一个获取用户订单信息的例子,演示复杂POJO中属性为List类型的数据绑定,案例具体实现步骤如下

1、修改User.java类,将User类中订单属性修改为List类型。由于用户一般拥有多个收货地址,在User类中新增List类型的地址属性。

java 复制代码
package org.example;

public class User{
        private String username;			//用户名
        private String password;			//用户密码
        private List<Order> orders;		//用户订单
        private List<String> address;		//订单地址

    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;
    }

    public List<Order> getOrders() {
        return orders;
    }

    public void setOrders(List<Order> orders) {
        this.orders = orders;
    }

    public List<String> getAddress() {
        return address;
    }

    public void setAddress(List<String> address) {
        this.address = address;
    }
}

2、创建一个订单处理器类OrderController,在OrderController类中定义showOrders( ) 方法,用于展示用户的订单信息。OrderController类的具体代码如下所示。

java 复制代码
    @Controller
    public class OrderController {//  获取用户中的订单信息
        @RequestMapping("/showOrders")
        public void showOrders(User user) {
            List<Order> orders = user.getOrders();List<String> addressList = user.getAddress();
            System.out.println("订单:");for (int i = 0; i <orders.size() ; i++) 
            {
                Order order = orders.get(i);
                String address = addressList.get(i);
                System.out.println("订单Id:"+order.getOrderId());
                System.out.println("订单配送地址:"+address);	
            }
        }
    }

3、创建一个订单信息文件orders.jsp,在orders.jsp中创建一个表单用于提交用户的订单信息。表单提交时,表单数据分别封装到User的订单属性orders和地址属性address中。orders.jsp的具体代码如下所示。

html 复制代码
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<html>
<head><title>订单信息</title></head>
<body>
<form action="${pageContext.request.contextPath }/showOrders"
      method="post">
    <table width="220px" border="1">
        <tr>
            <td>订单号</td>
            <td>订单名称</td>
            <td>配送地址</td>
        </tr>
        <tr>
            <td>
                <input name="orders[0].orderId" value="1" type="text">
            </td>
            <td>
                <input name="orders[0].orderName" value="Java基础教程"
                       type="text">
            </td>
            <td><input name="address" value="北京海淀" type="text"></td>
        </tr>
        <tr>
            <td>
                <input name="orders[1].orderId" value="2" type="text">
            </td>
            <td>
                <input name="orders[1].orderName" value="JavaWeb案例"
                       type="text">
            </td>
            <td><input name="address" value="北京昌平" type="text"></td>
        </tr>
        <tr>
            <td>
                <input name="orders[2].orderId" value="3" type="text">
            </td>
            <td>
                <input name="orders[2].orderName" value="SSM框架实战"
                       type="text">
            </td>
            <td><input name="address" value="北京朝阳" type="text"></td>
        </tr>
    </table>
    <input type="submit" value="订单信息"/>
</form>
</body>
</html>

4、启动chapter12项目,在浏览器中访问订单信息页面orders.jsp,访问地址为http://localhost:8080/chapter12/orders.jsp。

5、在orders.jsp显示效果图所示的页面中,单击左下角"订单信息"按钮,orders.jsp表单中的订单信息发送到服务器端的showOrders()方法进行处理,控制台打印信息如图所示。

java 复制代码
订单Id:1
订单配送地址:北京海淀
订单Id:2
订单配送地址:北京昌平
订单Id:3
订单配送地址:北京朝阳

从图中所示的打印信息可以得出,客户端中的请求参数成功绑定到了showOrders()方法的user形参中,完成了复杂POJO中属性为List类型的数据绑定。

六、复杂POJO数组绑定的编写要求

在复杂POJO数据绑定时,如果数据绑定到List类型的属性,客户端请求的参数名称(本例中指form表单内各元素name的属性值)编写必须符合以下要求。

①如果List的泛型为简单类型,则客户端参数名称必须和POJO类中List属性所属类中的属性名称保持一致。

②如果List的泛型参数为对象类型,则客户端参数名称必须与POJO类的层次结构名称保持一致,并使用数组格式描述对象在List中的位置,即客户端参数名称必须和最终绑定在List中的某个对象的某个属性的名称保持一致。

七、属性为Map类型的数据绑定

接下来,通过一个获取订单信息的案例,演示复杂POJO中属性为Map类型的数据绑定,具体实现如下。

1、修改Order.java类,在Order类中新增HashMap类型的属性productInfo,用于封装订单中的商品信息,其中productInfo的键用来存放商品的类别,productInfo的值用来存放商品类别对应的商品。

java 复制代码
public class Order {
    private String orderId;				//订单id
    private HashMap<String,Product> productInfo;	//商品信息
}

2、修改OrderController.java类,在OrderController类中新增getOrderInfo()方法,用于获取客户端提交的订单信息,并将获取到的订单信息打印在控制台。getOrderInfo()方法的具体代码如下所示。

java 复制代码
@RequestMapping("/orderInfo")
public void getOrderInfo(Order order) {
     String orderId = order.getOrderId();		//获取订单id
    //获取商品信息
    HashMap<String, Product> orderInfo = order.getProductInfo();
    Set<String> keys = orderInfo.keySet();
    System.out.println("订单id:"+orderId);	System.out.println("订单商品信息:");
     for (String key : keys) {	Product product = orderInfo.get(key);
	String proId = product.getProId();String proName = product.getProName();
	System.out.println( key+"类~"+"商品id:"+proId+",商品名称:"+proName);}}

3、创建一个订单信息页面order_info.jsp,在order_info.jsp中创建一个表单用于提交订单信息。表单提交时,表单数据分别封装到Order的orderId属性和商品信息属性productInfo中。

html 复制代码
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>订单信息</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/orderInfo"
      method="post">
    <table border="1">
        <tr>
            <td colspan="2">
                订单id:<input type="text" name="orderId" value="1">
            </td>
        </tr>
        <tr>
            <td>商品Id</td>
            <td>商品名称</td>
        </tr>
        <tr>
            <td>
                <input name="productInfo['生鲜'].proId" value="1"
                       type="text">
            </td>
            <td>
                <input name="productInfo['生鲜'].proName"
                       value="三文鱼" type="text">
            </td>
        </tr>
        <tr>
            <td>
                <input name="productInfo['酒水'].proId" value="2"
                       type="text">
            </td>
            <td>
                <input name="productInfo['酒水'].proName" value="红牛"
                       type="text">
            </td>
        </tr>
    </table>
    <input type="submit" value="提交"/>
</form>
</body>
</html>

八、数据绑定到Map类型的属性时的参数命名要求

在复杂POJO数据绑定时,如果数据绑定到Map类型的属性,客户端请求的参数名称(本例中指form表单内各元素name的属性值)必须与POJO类的层次结构名称保持一致,并使用键值的映射格式描述对象在Map中的位置,即客户端参数名称必须和要绑定的Map中的具体对象的具体属性的名称保持一致。

4、启动chapter12项目,在浏览器中访问订单信息页面order_info.jsp,访问地址为http://localhost:8080/chapter12/order_info.jsp。

5、在order_info.jsp显示效果图所示的页面中,单击左下角"提交"按钮,order_info.jsp表单中的订单信息发送到服务器端的getOrderInfo()方法进行处理,控制台打印信息如图所示。

java 复制代码
订单id:1
订单商品信息:
酒水类~商品id:2,商品名称:红牛
生鲜类~商品id:1,商品名称:三文鱼

由图所示打印的信息可以得出,客户端中的请求参数成功绑定到了getOrderInfo()方法的order形参中,完成了复杂POJO中属性为Map类型的数据绑定。

相关推荐
禁默16 分钟前
深入浅出:AWT的基本组件及其应用
java·开发语言·界面编程
Cachel wood23 分钟前
python round四舍五入和decimal库精确四舍五入
java·linux·前端·数据库·vue.js·python·前端框架
Code哈哈笑26 分钟前
【Java 学习】深度剖析Java多态:从向上转型到向下转型,解锁动态绑定的奥秘,让代码更优雅灵活
java·开发语言·学习
gb421528728 分钟前
springboot中Jackson库和jsonpath库的区别和联系。
java·spring boot·后端
程序猿进阶29 分钟前
深入解析 Spring WebFlux:原理与应用
java·开发语言·后端·spring·面试·架构·springboot
zfoo-framework37 分钟前
【jenkins插件】
java
风_流沙42 分钟前
java 对ElasticSearch数据库操作封装工具类(对你是否适用嘞)
java·数据库·elasticsearch
ProtonBase1 小时前
如何从 0 到 1 ,打造全新一代分布式数据架构
java·网络·数据库·数据仓库·分布式·云原生·架构
乐之者v1 小时前
leetCode43.字符串相乘
java·数据结构·算法