jackson:JSON字符串(String)类型的成员序列化和反序列化
对于如下类型定义TestTaskInfo,props字段为JSON字符串(这在数据库经常用到),可以自由保存各种类型的数据
@Data
public class TestTaskInfo {private String id;private String props;public TestTaskInfo() {}public TestTaskInfo(String id, String props) {super();this.id = id;this.props = props;}
}
如果对这样的字段直接序列化,效果就是这样:
TestTaskInfo info= new TestTaskInfo("0000", "{\"task_name\":\"RESET\",\"target_id\":22}");
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(info);
System.out.println(json);
输出
{"id":"0000","props":"{\"task_name\":\"RESET\",\"target_id\":22}"}
这个结果props字段被序列化为字符串,如果送给前端并不友好,前端还需要再对props字段进行解析才能得到里面的值。
@JsonRawValue
jackson的注解com.fasterxml.jackson.annotation.JsonRawValue可以解决上面的问题,它指示应按原样包含属性的文字字符串值来序列化字段。
所以给props字段增加@JsonRawValue就可以在序列化时将它不加双引号号,直接输出一个JSON对象而非字符串
@Data
public class TestTaskInfo {private String id;@JsonRawValueprivate String props;public TestTaskInfo() {}public TestTaskInfo(String id, String props) {super();this.id = id;this.props = props;}
}
效果是这样:
TestTaskInfo info= new TestTaskInfo("0000", "{\"task_name\":\"RESET\",\"target_id\":22}");
ObjectMapper mapper = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT);
String json = mapper.writeValueAsString(info);
System.out.println(json);
输出:
{"id" : "0000","props" : {"task_name":"RESET","target_id":22}
}
RawJsonDeserializer
解决了JSON字符串(String类型)字段序列化的问题,那么反序列化的问题又来了。
{"id" : "0000","props" : {"task_name":"RESET","target_id":22}
}
上面的输出在反序列化为TestTaskInfo对象时就会出问题,因为props的类型是String,但这个JSON中props是个OBJECT,所以在反序列化时会报错
com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.lang.String out of START_OBJECT token
要解决反序列化的问题,就得实现自定义的反序列化器。不论输入的JSON类型是什么,直接将内容段反序列化为String。这样就与props字段的类型匹配了。
以下是自定义反序列化器的实现:
import java.io.IOException;import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
/*** Deserializing JSON property as String with Jackson<br>* 实现将有{@link com.fasterxml.jackson.annotation.JsonRawValue}注解的* 内容为JSON的String类型字段反序列化为String的反序列化器实现**/
public class RawJsonDeserializer extends JsonDeserializer<String> {@Overridepublic String deserialize(JsonParser jp, DeserializationContext ctxt)throws IOException, JsonProcessingException {ObjectMapper mapper = (ObjectMapper) jp.getCodec();JsonNode node = mapper.readTree(jp);/** 将节点树输出为String */return mapper.writeValueAsString(node);}
}
我们再修改TestTaskInfo类型定义为props字段增加注解定义反序列化器:
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import gu.sql2java.json.RawJsonDeserializer;import lombok.Data;@Data
public class TestTaskInfo {private String id;@JsonRawValue@JsonDeserialize(using = RawJsonDeserializer.class)private String props;public TestTaskInfo() {}public TestTaskInfo(String id, String props) {super();this.id = id;this.props = props;}
}
再次测试:
import static org.junit.Assert.*;import org.junit.Test;import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;public class RawJsonDeserializerTest {@Testpublic void testJacksonCodec() {try {TestTaskInfo info= new TestTaskInfo("0000", "{\"task_name\":\"RESET\",\"target_id\":22}");ObjectMapper mapper = new ObjectMapper()/* .enable(SerializationFeature.INDENT_OUTPUT) */;/** 序列化 */String json = mapper.writeValueAsString(info);System.out.println(json);/** 反序列化 */TestTaskInfo parsed = mapper.readValue(json, TestTaskInfo.class);System.out.println(parsed.toString());assertTrue(parsed.equals(info));} catch (Throwable e) {e.printStackTrace();fail();}}}
这样就可以正常反序列化了,
输出
{“id”:“0000”,“props”:{“task_name”:“RESET”,“target_id”:22}}
TestTaskInfo(id=0000, props={“task_name”:“RESET”,“target_id”:22})
参考资料
《Deserializing JSON property as String with Jackson》
相关文章:
jackson:JSON字符串(String)类型的成员序列化和反序列化
对于如下类型定义TestTaskInfo,props字段为JSON字符串(这在数据库经常用到),可以自由保存各种类型的数据 Data public class TestTaskInfo {private String id;private String props;public TestTaskInfo() {}public TestTaskInfo(String id, String props) {super…...
使用docker的好处???(docker的优势)
标准化环境: Docker通过容器技术封装应用程序及其依赖(如库、配置文件、运行时环境等),确保应用程序在任何环境中都能以一致的方式运行。这种标准化消除了“在我机器上能运行”的问题,因为容器化应用能在开发、测试、生…...
Google AI 肺癌筛查的计算机辅助诊断
每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…...
【字符串算法题记录】反转字符串中的单词(leetcode),右旋字符串(kama)——双指针以及反转的奇思妙用
反转字符串中的单词 题目链接 思考 这题的思路顺序是:移除多余空格(双指针法)——》反转整个字符串)——》反转字符串中每个单词。 移除多余空格(双指针法) 因为字符串开头也可能有多个字符࿰…...
基于springboot+vue调用百度ai实现车牌号识别功能
百度车牌号识别官方文档 结果视频演示 后端代码 private String getCarNumber(String imagePath, int count) {// 请求urlString url "https://aip.baidubce.com/rest/2.0/ocr/v1/license_plate";try {byte[] imgData FileUtil.readFileByBytes(imagePath);Stri…...
【NTN 卫星通信】 TN和多NTN配合的应用场景
1 场景描述 此场景描述了农村环境,其中MNO (运营商TerrA)仅在城市附近提供本地地面覆盖,而MNO (SatA)提供广泛的NTN覆盖。SatA使用GSO轨道和NGSO轨道上的卫星。SatA与TerrA有漫游协议,允许: 所有TerrA用户的连接,当这些用户不…...
健康餐饮必备!油烟净化器超强洁净餐饮环境
我最近分析了餐饮市场的油烟净化器等产品报告,解决了餐饮业厨房油腻的难题,更加方便了在餐饮业和商业场所有需求的小伙伴们。 在如今注重健康生活的时代,餐饮业不仅需要美味佳肴,更需要一个清洁、舒适的用餐环境。油烟净化器作…...
Redis修改开源协议,6大备胎重见天日
背景:Redis2018年以来修改了多次开源协议,以前是把一些高级功能收费,这次彻底怒了,把核心代码的协议修改为RSALv2和SSPL双重协议,这个修改对普通用户不受影响,是向所有云厂商开炮,以后云厂商将不…...
使用python读取csv文件快速插入postgres数据库
使用python读取csv文件快速插入postgres数据库 下面为完整代码 import pandas as pd import cStringIO import warnings from sqlalchemy import create_engine import sys reload(sys) sys.setdefaultencoding(utf8) warnings.filterwarnings(ignore) engine create…...
【python地图添加指北针和比例尺】
文章目录 1、前言2、代码2.1、指北针2.2、比例尺 3、结果 1、前言 地理信息绘制中添加指北针和比例尺,使得图像更专业。 2、代码 2.1、指北针 def add_north(ax, labelsize18, loc_x0.95, loc_y0.99, width0.06, height0.09, pad0.14):"""画一个…...
VUE3——Proxy API 与VUE2——defineProperty API区别
一、Object.defineProperty 定义:Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象 为什么能实现响应式 通过defineProperty 两个属性,get及set get 属性的 getter 函…...
卷积神经网络(CNN):图像识别的强大工具
目录 1. 引言 2.卷积神经网络的基本原理 2.1.输入层 2.2.卷积层 2.3.池化层 2.4.激活层 2.5.全连接层(可选) 2.6.输出层 3.卷积神经网络的基本结构 4.卷积神经网络的训练过程 5.代码示例 6.总结 1. 引言 在图像处理与计算机视觉领域…...
【Java多线程】1——多线程知识回顾
1 多线程知识回顾 ⭐⭐⭐⭐⭐⭐ Github主页👉https://github.com/A-BigTree 笔记仓库👉https://github.com/A-BigTree/tree-learning-notes 个人主页👉https://www.abigtree.top ⭐⭐⭐⭐⭐⭐ 如果可以,麻烦各位看官顺手点个star…...
音视频处理 - 音频概念详解,码率,采样率,位深度,声道,编码
1. 音频采样 与视频不同,音频的最小单位不是一帧,而是一个采样。 采样是当前一刻声音的声音样本,样本需要经过数字转换才能存储为样本数据。 真实声音是连续的,但是在计算机中,声音是离散且均匀的声音样本。 2. 位深…...
【PLC】PROFIBUS(二):总线协议DP、PA、FMS
1、总线访问协议 (FDL) 1.1、多主通信 多个主设备间,使用逻辑令牌环依次向从设备发送命令。 特征: 主站间使用逻辑令牌环、主从站间使用主从协议主站在一个限定时间内 (Token Hold Time) 对总线有控制权从站只是响应一个主站的请求它们对总线没有控制…...
Mysql配置autocommit实际使用(慎用)
以下内容都是基于MySQL5.7。所有操作建议在MySQL客户端执行。navicat可能会先意想不到的问题 在导入频繁执行update、insert的时候,可以考虑关闭MySQL的自动提交 首先查询当前的状态 1开启 0关闭 select autocommit;设置本次连接关闭自动提交(如果需要永久关闭请修…...
Mac电脑高清媒体播放器:Movist Pro for mac下载
Movist Pro for mac是一款专为Mac操作系统设计的高清媒体播放器,支持多种常见的媒体格式,包括MKV、AVI、MP4等,能够流畅播放高清视频和音频文件。Movist Pro具有强大的解码能力和优化的渲染引擎,让您享受到更清晰、更流畅的观影体…...
Linux 网站定时备份+滚动删除脚本:文件、数据库(命令篇)
为确保数据安全,我们定期对网站相关文件和数据进行备份,以防止因各种原因导致的丢失情况。同时,考虑到服务器空间的限制,我们也会定期清理历史备份数据。 本文以 CentOS 7.9 系统为例,记录如何通过脚本和定时任务实现备…...
Cache缓存:HTTP缓存策略解析
🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 🍚 蓝桥云课签约作者、上架课程《Vue.js 和 E…...
智慧公厕的全域感知、全网协同、全业务融合和全场景智慧赋能
公共厕所是城市的重要组成部分,为市民提供基本的生活服务。然而,传统的公厕管理模式存在诸多问题,如排队等候时间长、卫生状况差、空气质量差等,严重影响市民的出行和生活质量。为了解决这些问题,智慧公厕应运而生&…...
使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...
装饰模式(Decorator Pattern)重构java邮件发奖系统实战
前言 现在我们有个如下的需求,设计一个邮件发奖的小系统, 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其…...
AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...
Oracle查询表空间大小
1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...
蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练
前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...
Java - Mysql数据类型对应
Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...
DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...
Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...
C# 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
Docker 本地安装 mysql 数据库
Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker ;并安装。 基础操作不再赘述。 打开 macOS 终端,开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...
