JFinal中如何实现反序列化----JSON字符串向Model对象转换

   需求: 将客户端传来的requestbody反序列化成对应的Model对象。

一、反序列化--驼峰命名

1、fastjson实现

   JFinal中没有提供反序列化的方法,因为大多数情况下,可以直接通过jar包进行转换,如利用fastjson,我们可以通过如下方式进行转换:

    JSON.parseArray(String jsonString, Class<T> class);
2、举个例子

  现有一个实体类:Book

@Data
pubilc class Book{private String bookName;private int bookPrice;
}

  将传过来的单个json数据转成对象:

String jsonStr = "{\"booktName\":\"钢铁是怎样练成的",\"bookPrice\":38.8}";
JSONArray jsonArray = JSON.parseArray(jsonStr);
Book book= (Book ) JSONObject.parseArray(jsonArray.toJSONString(), Book.class);

  将传过来的多个json数据转成对象:

String bookStr = "{\"bookList\":[{\"bookName\":\"钢铁是怎样炼成的\",\"bookPrice\":38.8},{\"bookName\":\"废柴是怎样堕落的\",\"bookPrice\":18.8}]}";
JSONObject bookJson = JSON.parseObject(bookStr );
JSONArray bookArray = bookJson .getJSONArray("bookList");
//第一种解析方式:直接解析为对象list
List<Book> booksList= JSONObject.parseArray(bookArray .toJSONString(), Book.class);

    但是如果在JFinal中这样写,编译的过程中他不会报错,但你会发现他存进去的都是空值,也就是说他在做类型转换的时候虽然识别到了这个Model,但是并不能和数据库表里的字段对应上。这是因为在数据表中,采用的是下划线"_"连接命名方式,而这种方法实际上是适用于驼峰命名的方式。

   为什么会造成这种情况呢?因为在jfinal里 Model中的getter、setter方法是按照驼峰命名的规则来生成,这时json中键值若使用数据库列名,当使用fastjson序列化时,我们会得到无法找到对应setter,从而也就无法更新其值。

接下来介绍如何解决:

二、反序列化--下划线"_"连接命名

 Object bookList= jsonObject.get("bookList");String jsonString = JSON.toJSONString( bookList, SerializerFeature.WriteMapNullValue);     List<Book> contactNoteList = parseArrayToModel(jsonString,Book.class);for (Booklist: contactNoteList) {list.set("head_id",book.get("id")).save();}

  这里设置SerializerFeature.WriteMapNullValue是因为,当传入的json以保留null值的键

//总体而言,此方法接受一个JSON数组字符串,解析它,并将每个JSON对象转换为指定模型类型的实例。它根据JSON对象中的键和值填充模型的属性,并返回这些填充好的模型的列表。public <T extends Model<T>> List<T> parseArrayToModel(String jsonString, Class<T> type) throws Exception {//初始化:List<T> list = new ArrayList<T>();JSONArray jsonArr = JSON.parseArray(jsonString);Table table = TableMapping.me().getTable(type); //使用TableMapping类的方法获取与给定模型类型相关联的表//模型解析循环:for (int i = 0; i < jsonArr.size(); i++) {T model = type.newInstance();//使用模型类型(T)的默认构造函数创建模型的新实例。JSONObject jsonObj = jsonArr.getJSONObject(i);//属性解析循环:for (String key : jsonObj.keySet()) {  //遍历JSON对象中的每个键。Class<?> colType = table.getColumnType(key);//从关联表中获取当前属性键的列类型。if (colType == null) { //如果未找到列类型(表示缺少属性),则抛出异常。throw new ActiveRecordException("The model attribute " + key + " is not exists.");}//值转换和模型填充:try {String paraValue = jsonObj.get(key) != null ? jsonObj.getString(key) : null;Object value = paraValue != null ? OpenJFinalMethod.convert(colType, paraValue) : null;  //尝试使用OpenJFinalMethod.convert方法将与当前键关联的JSON值转换为适当的类型。model.set(key, value); //使用model.set方法设置模型中的属性值。} catch (Exception e) {throw new RuntimeException("Can not convert parameter: " + key, e);}}//模型添加到列表:list.add(model); //返回包含解析后的模型的列表。}//返回语句:return list; //返回包含解析后的模型的列表。}

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.text.ParseException;
import java.text.SimpleDateFormat;/*** Convert String to other type object.*/
public class TypeConverter {private static Logger logger = LoggerFactory.getLogger(DocumentApiUtil.class);private static final String timeStampPattern = "yyyy-MM-dd HH:mm:ss";private static final String datePattern = "yyyy-MM-dd";private static final int dateLen = datePattern.length();/*** test for all types of mysql** 表单提交测试结果:* 1: 表单中的域,就算不输入任何内容,也会传过来 "", 也即永远不可能为 null.* 2: 如果输入空格也会提交上来* 3: 需要考 model中的 string属性,在传过来 "" 时是该转成 null还是不该转换,*    我想, 因为用户没有输入那么肯定是 null, 而不该是 ""** 注意: 1:当type参数不为String.class, 且参数s为空串blank的情况,*       此情况下转换结果为 null, 而不应该抛出异常*      2:调用者需要对被转换数据做 null 判断,参见 ModelInjector 的两处调用*/public static final Object convert(Class<?> type, String s) throws ParseException {// mysql type: varchar, char, enum, set, text, tinytext, mediumtext, longtextif (type == String.class) {return ("".equals(s) ? null : s);	// 用户在表单域中没有输入内容时将提交过来 "", 因为没有输入,所以要转成 null.}s = s.trim();if ("".equals(s)) {	// 前面的 String跳过以后,所有的空字符串全都转成 null,  这是合理的return null;}// 以上两种情况无需转换,直接返回, 注意, 本方法不接受null为 s 参数(经测试永远不可能传来null, 因为无输入传来的也是"")// mysql type: int, integer, tinyint(n) n > 1, smallint, mediumintif (type == Integer.class || type == int.class) {return Integer.parseInt(s);}// mysql type: bigintif (type == Long.class || type == long.class) {return Long.parseLong(s);}// java.util.Date 类型专为传统 java bean 带有该类型的 setter 方法转换做准备,万不可去掉// 经测试 JDBC 不会返回 java.util.Data 类型。java.sql.Date, java.sql.Time,java.sql.Timestamp 全部直接继承自 java.util.Data, 所以 getDate可以返回这三类数据if (type == java.util.Date.class) {if (s.length() > dateLen) {	// if (x < timeStampLen) 改用 datePattern 转换,更智能// Timestamp format must be yyyy-mm-dd hh:mm:ss[.fffffffff]// return new java.util.Date(java.sql.Timestamp.valueOf(s).getTime());	// error under jdk 64bit(maybe)return new SimpleDateFormat(timeStampPattern).parse(s);}else {// return new java.util.Date(java.sql.Date.valueOf(s).getTime());	// error under jdk 64bitreturn new SimpleDateFormat(datePattern).parse(s);}}// mysql type: date, yearif (type == java.sql.Date.class) {if (s.length() > dateLen) {	// if (x < timeStampLen) 改用 datePattern 转换,更智能// return new java.sql.Date(java.sql.Timestamp.valueOf(s).getTime());	// error under jdk 64bit(maybe)return new java.sql.Date(new SimpleDateFormat(timeStampPattern).parse(s).getTime());}else {// return new java.sql.Date(java.sql.Date.valueOf(s).getTime());	// error under jdk 64bitreturn new java.sql.Date(new SimpleDateFormat(datePattern).parse(s).getTime());}}// mysql type: timeif (type == java.sql.Time.class) {return java.sql.Time.valueOf(s);}// mysql type: timestamp, datetimeif (type == java.sql.Timestamp.class) {if (s.length() > dateLen) {return java.sql.Timestamp.valueOf(s);}else {return new java.sql.Timestamp(new SimpleDateFormat(datePattern).parse(s).getTime());}}// mysql type: real, doubleif (type == Double.class || type == double.class) {return Double.parseDouble(s);}// mysql type: floatif (type == Float.class || type == float.class) {return Float.parseFloat(s);}// mysql type: bit, tinyint(1)if (type == Boolean.class || type == boolean.class) {String value = s.toLowerCase();if ("1".equals(value) || "true".equals(value)) {return Boolean.TRUE;}else if ("0".equals(value) || "false".equals(value)) {return Boolean.FALSE;}else {throw new RuntimeException("Can not parse to boolean type of value: " + s);}}// mysql type: decimal, numericif (type == java.math.BigDecimal.class) {return new java.math.BigDecimal(s);}// mysql type: unsigned bigintif (type == java.math.BigInteger.class) {return new java.math.BigInteger(s);}// mysql type: binary, varbinary, tinyblob, blob, mediumblob, longblob. I have not finished the test.if (type == byte[].class) {return s.getBytes();}throw new RuntimeException(type.getName() + " can not be converted, please use other type of attributes in your model!");}}

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

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

相关文章

Renitialized existing Git repositoy in D:/libai/project/gitab-cicd-test/.git/

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

vue 引入 百度地图API 和 路书

公司项目中&#xff0c;偶尔都会涉及到地图的使用&#xff0c;这里以百度地图为例&#xff0c;我们梳理一下引用流程及注意点 账号和获取密钥 百度地图示例 百度地图 类参考 1、账号和获取密钥 // api.map.baidu.com/api?typewebgl&v3.0&ak您的密钥<script type…

1899_野火FreeRTOS教程阅读笔记_任务创建

1899_野火FreeRTOS教程阅读笔记_任务创建 全部学习汇总&#xff1a; g_FreeRTOS: FreeRTOS学习笔记 (gitee.com) 关于这部分&#xff0c;从一般前后台程序到RTOS的任务描述了很多。但是我觉得这本书的这部分描述没有描述到关键的信息点。其实&#xff0c;RTOS存在的一个主要的目…

机器学习系列——(十七)聚类

引言 在当今数据驱动的时代&#xff0c;机器学习已经成为了解锁数据潜能的关键技术之一。其中&#xff0c;聚类作为机器学习领域的一个重要分支&#xff0c;广泛应用于数据挖掘、模式识别、图像分析等多个领域。本文旨在深入探讨聚类技术的原理、类型及其应用&#xff0c;为读…

【Flink入门修炼】1-3 Flink WordCount 入门实现

本篇文章将带大家运行 Flink 最简单的程序 WordCount。先实践后理论&#xff0c;对其基本输入输出、编程代码有初步了解&#xff0c;后续篇章再对 Flink 的各种概念和架构进行介绍。 下面将从创建项目开始&#xff0c;介绍如何创建出一个 Flink 项目&#xff1b;然后从 DataStr…

IDEA创建Java类时自动添加注释(作者、年份、月份)

目录 IDEA创建Java类时自动添加注释&#xff08;作者、年份、月份&#xff09;如图&#xff1a; IDEA创建Java类时自动添加注释&#xff08;作者、年份、月份&#xff09; 简单记录下&#xff0c;IDEA创建Java类时自动添加注释&#xff08;作者、年份、月份&#xff09;&#…

Java+微信小程序实现智慧家政系统 JAVA+Vue+SpringBoot+MySQL

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、系统展示四、核心代码4.1 查询家政服务4.2 新增单条服务订单4.3 新增留言反馈4.4 小程序登录4.5 小程序数据展示 五、免责说明 一、摘要 1.1 项目介绍 基于微信小程序JAVAVueSpringBootMySQL的智慧家政系统&#xff0…

【SparkML实践7】特征选择器FeatureSelector

本节介绍了用于处理特征的算法&#xff0c;大致可以分为以下几组&#xff1a; 提取&#xff08;Extraction&#xff09;&#xff1a;从“原始”数据中提取特征。转换&#xff08;Transformation&#xff09;&#xff1a;缩放、转换或修改特征。选择&#xff08;Selection&…

作业2.8

1、选择题 1.1、以下选项中,不能作为合法常量的是 ____B______ A&#xff09;1.234e04 B&#xff09;1.234e0.4 C&#xff09;1.234e4 D&#xff09;1.234e0 1.2、以下定义变量并初始化错误的是_____D________。 A) char c1 ‘H’ &#xff1b; B) char c…

RabbitMQ高可用架构涉及常用功能整理

RabbitMQ高可用架构涉及常用功能整理 1. rabbitmq的集群模式2. 镜像模式高可用系统架构和相关组件3. rabbitmq的核心参数3.1 镜像策略3.2 新镜像同步策略3.3 从节点晋升策略3.4 主队列选择策略 4. rabbitmq常用命令4.1 常用基础命令4.1.1 服务管理4.1.2 用户管理4.1.3 角色管理…

数字图像处理(实践篇)四十七 OpenCV-Python 高动态范围HDR

目录 一 HDR 二 实践 高质量的图像具备的要素如下: ①分辨率 图像中的像素数量。在特定屏幕尺寸下,分辨率越高,像素越多,显示的细节更精细。 ②位深度

JavaEE作业-实验三

目录 1 实验内容 2 实验要求 3 思路 4 核心代码 5 实验结果 1 实验内容 简单的线上图书交易系统的web层 2 实验要求 ①采用SpringMVC框架&#xff0c;采用REST风格 ②要求具有如下功能&#xff1a;商品分类、订单、购物车、库存 ③独立完成&#xff0c;编写实验报告 …

OOP设计模式与JAVA之间存在怎么样的关系?

面向对象程序设计&#xff08;Object Oriented Programming&#xff0c;OOP&#xff09;是一种程序设计范型&#xff0c;它以对象为基础&#xff0c;将数据和操作封装在一起&#xff0c;形成一个独立的实体。OOP设计模式是面向对象程序设计的一种应用&#xff0c;它提供了一种在…

自然语言处理(NLP)——使用Rasa创建聊天机器人

1 基本概念 1.1 自然语言处理的分类 IR-BOT&#xff1a;检索型问答系统 Task-bot&#xff1a;任务型对话系统 Chitchat-bot:闲聊系统 1.2 任务型对话Task-Bot:task-oriented bot 这张图展示了一个语音对话系统&#xff08;或聊天机器人&#xff09;的基本组成部分和它们之间的…

外贸邮件群发如何做?外贸邮件群发靠谱吗?

外贸邮件群发有哪些平台&#xff1f;外贸群发邮件用什么邮箱&#xff1f; 外贸邮件群发是许多企业在开展国际贸易时常用的营销手段&#xff0c;它不仅能够快速地将产品信息和促销活动传达给目标客户&#xff0c;还能够有效地建立和维护客户关系。下面&#xff0c;就让蜂邮探讨…

【JavaScript】switch 语句

文章目录 1. 基础的 switch 语句2. 多个条件的处理3. 使用 switch 进行条件判断4. switch 语句 vs if-else 语句5. 总结 在 JavaScript 中&#xff0c; switch 语句是一种 用于根据不同的条件值执行不同代码块的控制流结构。本篇博客将介绍 JavaScript 中的 switch 语句&…

跟着pink老师前端入门教程-day21+22

5.4 常见flex布局思路 5.5 背景线性渐变 语法&#xff1a; background: linear-gradient( 起始方向 , 颜色 1, 颜色 2, ...); background: -webkit-linear-gradient(left, red , blue); background: -webkit-linear-gradient(left top, red , blue); 背景渐变必须添加浏览…

e5 服务器具备哪些性能特点?

随着云计算和大数据技术的不断发展&#xff0c;服务器作为数据中心的核心设备&#xff0c;其性能特点也日益受到关注。其中&#xff0c;E5服务器作为当前主流的服务器类型之一&#xff0c;具备许多优秀的性能特点。本文将详细介绍E5服务器的性能特点&#xff0c;帮助读者更好地…

CTFshow web(php命令执行 37-40)

?ceval($_GET[shy]);&shypassthru(cat flag.php); #逃逸过滤 ?cinclude%09$_GET[shy]?>&shyphp://filter/readconvert.base64-encode/resourceflag.php #文件包含 ?cinclude%0a$_GET[cmd]?>&cmdphp://filter/readconvert.base64-encode/…

(41)速算机器人

文章目录 每日一言题目解题思路代码结语 每日一言 愚昧从来没有给人带来幸福&#xff1b;幸福的根源在于知识。——左拉 题目 题目链接&#xff1a;速算机器人 小扣在秋日市集发现了一款速算机器人。店家对机器人说出两个数字&#xff08;记作 x 和 y&#xff09;&#xff0…