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

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

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

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

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

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

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

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

public class Order {private String orderId;            //订单idpublic String getOrderId() {return orderId;}public void setOrderId(String orderId) {this.orderId = orderId;}
}

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

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( )方法的具体代码如下所示。

@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的具体代码如下所示。

<%@ 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”,单击“查询”按钮,控制台打印信息如下图所示。

username=享受,oederId=9527

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

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

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

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类的具体代码如下所示。

    @Controllerpublic 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的具体代码如下所示。

<%@ 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()方法进行处理,控制台打印信息如图所示。

订单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的值用来存放商品类别对应的商品。

public class Order {private String orderId;				//订单idprivate HashMap<String,Product> productInfo;	//商品信息
}

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

@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中。

<%@ 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()方法进行处理,控制台打印信息如图所示。

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/862198.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AI进阶指南第四课,大模型优缺点研究?

在上一篇文章中&#xff0c;我主要探讨了LM模型与企业级模型的融合。 但是&#xff0c;在文末对于具体的大模型优缺点只是简单地说明了一下&#xff0c;并不细致。 因此&#xff0c;在这一节&#xff0c;我将更为细致地说明一下大模型的优缺点。 一&#xff0c;隐私安全 将L…

2018年全国大学生数学建模竞赛A题高温服装设计(含word论文和源代码资源)

文章目录 一、部分题目二、部分论文三、部分Matlab源代码问题11 求解h1h22 已知h1h2求解温度分布 问题21 求解第二层最佳厚度 四、完整word版论文和源代码&#xff08;两种获取方式&#xff09; 一、部分题目 2018 年高教社杯全国大学生数学建模竞赛题目 A 题 高温作业专用服…

vCenter- KMS Server healthy warning

- 问题摘要&#xff1a;KMS Server healthy warning. - 分析/故障排除: 检查集群配置-Security-Key Providers界面&#xff0c;发现KMS Server并没有完整配置并且目前集群内的虚机没有使用加密功能&#xff08;VM Encryption&#xff09;&#xff0c;您可以忽略该告警提示。 …

Linux C 程序 【02】创建线程

1.开发背景 上一个篇章&#xff0c;基于 RK3568 平台的基础上&#xff0c;运行了最简单的程序&#xff0c;然而我们使用了 Linux 系统&#xff0c;系统自带的多线程特性还是比较重要的&#xff0c;这个篇章主要描述线程的创建。 2.开发需求 设计实验&#xff1a; 创建一个线程…

【linux】find命令详解

Linux中的find命令用于在文件系统中搜索符合条件的文件或目录。 一.基本语法 find [path] [expression] #path:搜索的起始目录&#xff0c;如果不指定&#xff0c;默认为当前目录 #expression&#xff1a;定义搜索条件的表达式 命令选项 -name 按文件名搜索 -size …

入门JavaWeb之 JavaBean 实体类

JavaBean 有特定写法&#xff1a; 1.必须有一个无参构造 2.属性必须私有 3.必须有对应的 get/set 方法 一般用来和数据库的字段做映射 ORM&#xff1a;对象关系映射 表->类 字段->属性 行记录->对象 连接数据库 没有的话去 Settings -> Plugins 搜索 Data…

Vue-路由

路由简介 SPA单页面应用。导航区和展示区 单页Web应用整个应用只有一个完整的页面点击页面中的导航连接不会刷新页面&#xff0c;只会做页面的局部更新数据需要通过ajax请求获取 路由&#xff1a;路由就是一组映射关系&#xff0c;服务器接收到请求时&#xff0c;根据请求路…

[论文阅读笔记33] Matching Anything by Segmenting Anything (CVPR2024 highlight)

这篇文章借助SAM模型强大的泛化性&#xff0c;在任意域上进行任意的多目标跟踪&#xff0c;而无需任何额外的标注。 其核心思想就是在训练的过程中&#xff0c;利用strong augmentation对一张图片进行变换&#xff0c;然后用SAM分割出其中的对象&#xff0c;因此可以找到一组图…

k8s集群node节点加入失败

出现这种情况&#xff1a; [preflight] FYI: You can look at this config file with kubectl -n kube-system get cm kubeadm-config -o yaml [kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml" [kubelet-start] Writing kub…

python 识别图片点击,设置坐标,离设置坐标越近的优先识别点击

import pyautogui import cv2 import numpy as np import mathdef find_and_click(template_path, target_x, target_y, match_threshold0.8):"""在屏幕上查找目标图片并点击。Args:template_path: 目标图片的路径。target_x: 预设的坐标 x 轴值。target_y: 预设…

【Android面试八股文】如何优化二维码的扫描速度?

文章目录 一、 普通优化1.1 解码优化1.1.1 减少解码格式1.1.2 解码算法优化1.1.3. 减少解码数据1.1.4. Zbar 与 Zxing融合1.2 优化相机设置1.2.1. 选择最佳预览尺寸/图片尺寸1.2.2. 设置适合的相机放大倍数1.2.3. 调整聚焦时间1.2.4. 设置自动对焦区域1.2.5. 调整合理扫描区域1…

OpenCV报错已解决:Vector析构异常OpencvAssert CrtlsValidHeapPointer

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 引入 在使用OpenCV进行图像处理时&#xff0c;我们可能会遇到Vector析构异常OpencvAssert CrtlsValidHeapPointer的问题。本文将…

基于LMS自适应滤波的窄带信号宽带噪声去除(MATLAB R2021B)

数十年的研究极大的发展了自适应滤波理论&#xff0c;自适应滤波理论已经成为信号处理领域研究的热点之一。从理论上讲&#xff0c;自适应滤波问题没有唯一解。为了得到自适应滤波器及其应用系统&#xff0c;可以根据不同的优化准则推导出许多不同的自适应理论。目前该理论主要…

在eclipse中导入idea项目步骤

一、可以把其它项目的.project&#xff0c; .classpath文件拷贝过来&#xff0c;修改相应的地方则可。 1、.project文件只需要修改<name>xxx</name>这个项目名称则可 2、.classpath文件通常不用改&#xff0c; 二、右击 项目名 >选择“Properties”>选择 Re…

自动驾驶⻋辆环境感知:多传感器融合

目录 一、多传感器融合技术概述 二、基于传统方法的多传感器融合 三、基于深度学习的视觉和LiDAR的目标级融合 四、基于深度学习的视觉和LiDAR数据的前融合方法 概念介绍 同步和配准 时间同步 标定 摄像机内参标定&#xff08;使用OpenCV&#xff09; 摄像机与LiDAR外…

分库分表相关概念

分库分表相关概念 文章目录 分库分表相关概念分库分表的概念水平分库分表水平分表水平分库水平分库分表的实现方式 垂直分库分表垂直分表垂直分库 分库分表的挑战 核心概念一、逻辑表二、物理表三、数据节点四、绑定表&#xff08;Binding Table&#xff09;五、广播表&#xf…

ASP.NET Core Blazor 3:使用 Blazor Server (2)

1 准备工作 继续使用上一章项目。   本章展示如何组合Razor组件来创建更复杂的特性。展示如何创建组件之间的父子关系&#xff0c;如何利用属性配置组件&#xff0c;以及如何创建自定义事件&#xff0c;以在发生重要更改时发出信号。还展示了组件如何从父组件接收内容&#x…

C语言 有一函数,当x<0则y=-1,当x=1则y=0,当x>0则y=1,以下是关于该函数的两个c程序,请分析它们是否能实现函数的要求?

题目代码&#xff1a; &#xff08;1&#xff09; #include<stdio.h>int main(){int x,y;printf(“enter x:”);scanf(“%d”,&x);y-1;if(x!0)if(x>0)y1;elesy0;printf(“x%d,y%d\n”,x,y);return 0;} (2) #include<stdio.h>int main(){int x,y;printf(…

软考初级网络管理员__编程单选题

1.为了提高程序的可读性&#xff0c;在编写源程序时需要。 添加注释 减少全局变量 注重程序执行效率 减少存储空间 2.在应用程序开发中&#xff0c;从源代码到可执行文件&#xff0c;需要经过四个步骤&#xff0c;将汇编代码转变为机器可以执行的指令的过程称为()。 预编…

微软推出最新视觉基础模型Florence-2 可在浏览器运行

据微软官方消息&#xff0c;微软推出视觉基础模型Florence-2&#xff0c;该模型现已能够在支持WebGPU的浏览器中100%本地运行。Florence-2-base-ft是一个拥有2.3亿参数的视觉基础模型&#xff0c;采用基于提示的方法来处理广泛的视觉和视觉语言任务。 该模型支持多种功能&…