当前位置: 首页 > news >正文

Gson 问题汇总

Gson 自定义TypeAdapter

  • 使用Gson
    • springboot中指定Gson为默认消息转换器
    • 自定义Gson实例
    • 解决方法
        • 设定日期类型的格式
        • 处理特殊格式数据
        • 解析serialVersionUID字段报错
        • int类型,转换后变成了double类型

使用Gson

gson是google推出的json解析框架,相较于其他json解析框架,它速度更快也更安全(网上有很多资料,这里就不赘述了),在maven项目中使用gson,只需要引入以下配置即可,这里使用的2.8.5版本

 <dependency> <groupId>com.google.code.gson</groupId><artifactId>gson</artifactId><version>2.8.5</version></dependency>

springboot中指定Gson为默认消息转换器

在springBoot中注入定义的HttpMessageConverter 即可(若使用的其他json框架,注入相应的HttpMessageConverter),例如:

@Configuration
public class WebConfig implements WebMvcConfigurer {@Beanpublic HttpMessageConverter GsonHttpMessageConverter() {GsonHttpMessageConverter gsonHttpMessageConverter = new GsonHttpMessageConverter();gsonHttpMessageConverter.setGson(new Gson());//放入Gson实例return gsonHttpMessageConverter;}}

自定义Gson实例

在Gson使用过程中,可能遇到多种情况,例如:

  • 需要设定日期类型的格式
  • 处理特殊格式数据
  • 在解析serialVersionUID字段时发生 class declares multiple JSON fields named serialVersionUid
  • json字符串中的int类型,转换后变成了double类型

解决方法

设定日期类型的格式

第一种方式:
使用JsonDeserializer来指定反序列化(解析)方式,与此对应的还有JsonSerializer接口,用来指定对象序列化方式:

//设定Date类型的反序列化(解析)规则private static final com.google.gson.JsonDeserializer<Date> deser = new com.google.gson.JsonDeserializer<Date>() {@Overridepublic Date deserialize(JsonElement json, Type typeOfT,JsonDeserializationContext context) throws JsonParseException {String date = json.getAsString();SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");format.setTimeZone(TimeZone.getTimeZone("GMT"));try {return format.parse(date);} catch (ParseException exp) {System.err.println(exp.getMessage());return null;}}};private final static Gson INSTANCE = new GsonBuilder().serializeNulls().registerTypeAdapter(Date.class, deser).create();//制定Date类型的转换器

第二种方式:

   private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";private final static Gson INSTANCE = new GsonBuilder().serializeNulls().setDateFormat(DATE_FORMAT).create();//此规则 将用于序列化与反序列化Date对象,如果多次指定此规则,将以最后一次为准

第二种方式=JsonDeserializer+JsonSerializer
如果项目中已经约定好使用统一的日期格式,使用第二种方式更简便易读

处理特殊格式数据

在某场景中,原本是double类型的数据,在上百条数据中,有几条数据因为数据为空,我接收到是"-“,一转换就报类型无法转换错误(因为是爬取数据),我只能自己想办法把”-"转为——(double)0

    @Testvoid contextLoads() {String dataJson = "{\"number\" : 30.2, \"amount\" : \"-\"}";Gson gson = GsonUtils.getSingleton();Map map = gson.fromJson(dataJson, Map.class);System.out.println(map);}

解决:

        public static final TypeAdapter<Number> NumberFormat = new TypeAdapter<Number>() {@Overridepublic Number read(JsonReader in) throws IOException {if (in.peek() == JsonToken.NULL) {in.nextNull();return 0;}try {double i = in.nextDouble();return  i;} catch (NumberFormatException e) {//如果报数字格式化异常,判断是否为目标字符串if (e.getMessage().contains("-")){Class<JsonReader> jsonReaderClass = JsonReader.class;try {Field peekedString = jsonReaderClass.getDeclaredField("peekedString");peekedString.setAccessible(true);peekedString.set(in,"0.0");//通过反射更改了json字符串中原"-"为0.0double i = in.nextDouble();//更改值后重新计算return  i;} catch (NoSuchFieldException ex) {ex.printStackTrace();} catch (IllegalAccessException ex) {ex.printStackTrace();}return  0.0;}else {throw new JsonSyntaxException(e);}}}@Overridepublic void write(JsonWriter out, Number value) throws IOException {out.value(value);}};private final static Gson INSTANCE = new GsonBuilder().serializeNulls().disableHtmlEscaping()//默认情况下,Gson会转义HTML字符,例如<>等。使用此选项将 Gson配置为直接传递HTML字符.registerTypeAdapter(Date.class, deser).registerTypeAdapter(Double.class, NumberFormat).registerTypeAdapter(double.class, NumberFormat).create();

由于registerTypeAdapter只注册指定的类型,不会注册相关类型,所以注册Double时,也需要注册double类型,贴出registerTypeAdapter方法源码以及注释:

 /*** Configures Gson for custom serialization or deserialization. This method combines the* registration of an {@link TypeAdapter}, {@link InstanceCreator}, {@link JsonSerializer}, and a* {@link JsonDeserializer}. It is best used when a single object {@code typeAdapter} implements* all the required interfaces for custom serialization with Gson. If a type adapter was* previously registered for the specified {@code type}, it is overwritten.** <p>This registers the type specified and no other types: you must manually register related* types! For example, applications registering {@code boolean.class} should also register {@code* Boolean.class}.** @param type the type definition for the type adapter being registered* @param typeAdapter This object must implement at least one of the {@link TypeAdapter},* {@link InstanceCreator}, {@link JsonSerializer}, and a {@link JsonDeserializer} interfaces.* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern*/@SuppressWarnings({"unchecked", "rawtypes"})public GsonBuilder registerTypeAdapter(Type type, Object typeAdapter) {$Gson$Preconditions.checkArgument(typeAdapter instanceof JsonSerializer<?>|| typeAdapter instanceof JsonDeserializer<?>|| typeAdapter instanceof InstanceCreator<?>|| typeAdapter instanceof TypeAdapter<?>);if (typeAdapter instanceof InstanceCreator<?>) {instanceCreators.put(type, (InstanceCreator) typeAdapter);}if (typeAdapter instanceof JsonSerializer<?> || typeAdapter instanceof JsonDeserializer<?>) {TypeToken<?> typeToken = TypeToken.get(type);factories.add(TreeTypeAdapter.newFactoryWithMatchRawType(typeToken, typeAdapter));}if (typeAdapter instanceof TypeAdapter<?>) {factories.add(TypeAdapters.newFactory(TypeToken.get(type), (TypeAdapter)typeAdapter));}return this;}

大家不一定会遇到一摸一样的场景,这里只是提供一个思路

解析serialVersionUID字段报错

在项目中,出现:class declares multiple JSON fields named serialVersionUid异常
解决:

  private static final List<String> EXCLUDE = new ArrayList<String>() {{add("serialVersionUID");}};private final static Gson INSTANCE = new GsonBuilder().serializeNulls().setExclusionStrategies(new ExclusionStrategy() {@Overridepublic boolean shouldSkipField(FieldAttributes f) {boolean exclude = false;try {exclude = EXCLUDE.contains(f.getName());} catch (Exception ignore) {}return exclude;}@Overridepublic boolean shouldSkipClass(Class<?> aClass) {return false;}})//制定排除策略.disableHtmlEscaping()//默认情况下,Gson会转义HTML字符,例如<>等。使用此选项将 Gson配置为直接传递HTML字符.registerTypeAdapter(Date.class, deser).registerTypeAdapter(Double.class, NumberFormat).registerTypeAdapter(double.class, NumberFormat).create();
int类型,转换后变成了double类型

参考
Error: Class declares multiple JSON fields named serialVersionUid

相关文章:

Gson 问题汇总

Gson 自定义TypeAdapter 使用Gsonspringboot中指定Gson为默认消息转换器自定义Gson实例解决方法设定日期类型的格式处理特殊格式数据解析serialVersionUID字段报错int类型,转换后变成了double类型 使用Gson gson是google推出的json解析框架,相较于其他json解析框架,它速度更快…...

css-水滴登录页

效果图&#xff1a; html <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title><link type"text/css" rel"stylesheet" href"login.css" /></head><body><…...

Spark Streaming 整合 Flume

本文代码链接: https://download.csdn.net/download/shangjg03/88442192 1.简介 Apache Flume 是一个分布式,高可用的数据收集系统,可以从不同的数据源收集数据,经过聚合后发送到分布式计算框架或者存储系统中。Spark Straming 提供了以下两种方式用于 Flume 的整合。 2.推…...

如何写出优雅的业务代码

接口统一响应对象返回 BaseResponse通用响应对象 package com.leesin.project.common;存放在common包下 有三个主要的字段&#xff1a; code&#xff1a;一个整数&#xff0c;通常用于表示响应的状态码&#xff0c;例如200表示成功&#xff0c;404表示未找到资源等。data&a…...

办鹿uniapp小程序(一)

一、项目初始化 1. appid 》 公司给你 wxc82730a0fc15e28a 2. 开发者身份 》 公司给你添加 小程序官网&#xff1a;小程序 管理》成员管理》项目成员 1、 uniapp ui组件 &#xff08;uView&#xff09; 如果采用npm安装方式在 小程序端不生效 1.1 采用插件的形式安装&#xf…...

#力扣:1684. 统计一致字符串的数目@FDDLC

1684. 统计一致字符串的数目 - 力扣&#xff08;LeetCode&#xff09; 一、Java class Solution {public int countConsistentStrings(String allowed, String[] words) {boolean[] isAllowed new boolean[26];for(int i 0; i < allowed.length(); i) isAllowed[allowed…...

谈谈 Redis 主从复制模式

谈谈 Redis 主从复制模式 第一次主从节点同步是全量复制 接下来&#xff0c;我在具体介绍每一个阶段都做了什么。 第一阶段&#xff1a;建立链接、协商同步 执行了 replicaof 命令后&#xff0c;从服务器就会给主服务器发送 psync 命令&#xff0c;表示要进行数据同步。 psync…...

tika解压遇到压缩炸弹如何继续解压

1.问题 项目中要对10层压缩的zip、7z等文件用tika解压遇到错误&#xff1a;tika zip bomb detected 也就是说tika认为这是个压缩炸弹。 “压缩炸弹”是一个压缩包文件的木马程序&#xff0c;通常只有几百KB&#xff0c;解压后会变成上百MB或者上GB庞然大物。把你本地磁盘占满…...

【OJ比赛日历】快周末了,不来一场比赛吗? #10.21-10.27 #11场

CompHub[1] 实时聚合多平台的数据类(Kaggle、天池…)和OJ类(Leetcode、牛客…&#xff09;比赛。本账号会推送最新的比赛消息&#xff0c;欢迎关注&#xff01; 以下信息仅供参考&#xff0c;以比赛官网为准 目录 2023-10-21&#xff08;周六&#xff09; #2场比赛2023-10-22…...

如何远程通过内网穿透实现微信公众号在本地的完整调试

文章目录 前言1. 配置本地服务器2. 内网穿透2.1 下载安装cpolar内网穿透2.2 创建隧道 3. 测试公网访问4. 固定域名4.1 保留一个二级子域名4.2 配置二级子域名 5. 使用固定二级子域名进行微信开发 前言 在微信公众号开发中&#xff0c;微信要求开发者需要拥有自己的服务器资源来…...

【LeetCode刷题(数据结构与算法)】:合并两个有序链表

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的 **思路&#xff1a;定义一个头尾指针置为NULL while循环依次比较两个链表的值的大小 遍历链表 比较完数值大小过后连接到tail的尾部 然后各自的链表的节点的next指针指向下一…...

spark DStream从不同数据源采集数据(RDD 队列、文件、diy 采集器、kafka)(scala 编程)

目录 1. RDD队列 2 textFileStream 3 DIY采集器 4 kafka数据源【重点】 1. RDD队列 a、使用场景&#xff1a;测试 b、实现方式: 通过ssc.queueStream(queueOfRDDs)创建DStream&#xff0c;每一个推送这个队列的RDD&#xff0c;都会作为一个DStream处理 val sparkco…...

【三:Mock服务的使用】

目录 1、工具包2、mock的demo1、get请求2、post请求3、带cookies的请求4、带请求头的请求5、请求重定向 1、工具包 1、&#xff1a;服务包的下载 moco-runner-0.11.0-standalone.jar 下载 2、&#xff1a;运行命令java -jar ./moco-runner-0.11.0-standalone.jar http -p 888…...

驱动:驱动相关概念,内核模块编程,内核消息打印printk函数的使用

一、驱动相关概念 1.操作系统的功能 向下管理硬件&#xff0c;向上提供接口 操作系统向上提供的接口类型&#xff1a; 内存管理&#xff1a;内存申请&#xff08;malloc&#xff09; 内存释放&#xff08;free&#xff09;等 文件管理&#xff1a; 通过文件系统格式对文件ext2…...

【Qt控件之QListWidget】介绍及使用,利用QListWidget、QToolButton、和布局控件实现抽屉式组合控件

概述 QListWidget类提供了基于项目的列表小部件。 QListWidget是一个方便的类&#xff0c;类似于QListView提供的列表视图&#xff0c;但使用经典的基于项目的接口来添加和删除项目。QListWidget使用内部模型来管理列表中的每个QListWidgetItem。 对于更灵活的列表视图小部件…...

【Java基础面试二十四】、String类有哪些方法?

文章底部有个人公众号&#xff1a;热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享&#xff1f; 踩过的坑没必要让别人在再踩&#xff0c;自己复盘也能加深记忆。利己利人、所谓双赢。 面试官&#xff1a;String类有哪些方法&…...

[DRAFT] LLVM ThinLTO原理分析

我们在《论文阅读&#xff1a;ThinLTO: Scalable and Incremental LTO》中介绍了ThinLTO论文的主要思想&#xff0c;这里我们介绍下LLVM ThinLTO是如何实现的。本文主要分为如下几个部分&#xff1a; LLVM ThinLTO Object 含有哪些内容&#xff1f;LLVM ThinLTO 是如何做优化的…...

使用Gitlab构建简单流水线CI/CD

什么是Gitlab Gitlab实质上是一套DevOps工具 目前看起来&#xff0c;Gitlab属于是内嵌了一套CI/CD的框架&#xff0c;并且可以提供软件开发中的版本管理、项目管理等等其他功能。 这里需要辨别一下Gitlab和Github Gitee的区别。 GIthub大家都很熟悉了&#xff0c;一般大家都会…...

【AIGC核心技术剖析】用于高效 3D 内容创建生成(从单视图图像生成高质量的纹理网格)

3D 内容创建的最新进展主要利用通过分数蒸馏抽样 &#xff08;SDS&#xff09; 生成的基于优化的 3D 生成。尽管已经显示出有希望的结果&#xff0c;但这些方法通常存在每个样本优化缓慢的问题&#xff0c;限制了它们的实际应用。在本文中&#xff0c;我们提出了DreamGaussian&…...

nginx平滑升级添加echo模块、localtion配置、rewrite配置

nginx平滑升级添加echo模块、location配置、rewrite配置 文章目录 nginx平滑升级添加echo模块、location配置、rewrite配置1.环境说明&#xff1a;2.nginx平滑升级原理&#xff1a;3.平滑升级nginx&#xff0c;并添加echo模块3.1.查看当前nginx版本以及老版本编译参数信息3.2.下…...

Vue记事本应用实现教程

文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展&#xff1a;显示创建时间8. 功能扩展&#xff1a;记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

day52 ResNet18 CBAM

在深度学习的旅程中&#xff0c;我们不断探索如何提升模型的性能。今天&#xff0c;我将分享我在 ResNet18 模型中插入 CBAM&#xff08;Convolutional Block Attention Module&#xff09;模块&#xff0c;并采用分阶段微调策略的实践过程。通过这个过程&#xff0c;我不仅提升…...

DockerHub与私有镜像仓库在容器化中的应用与管理

哈喽&#xff0c;大家好&#xff0c;我是左手python&#xff01; Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库&#xff0c;用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...

centos 7 部署awstats 网站访问检测

一、基础环境准备&#xff08;两种安装方式都要做&#xff09; bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats&#xff0…...

Golang dig框架与GraphQL的完美结合

将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用&#xff0c;可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器&#xff0c;能够帮助开发者更好地管理复杂的依赖关系&#xff0c;而 GraphQL 则是一种用于 API 的查询语言&#xff0c;能够提…...

土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等

&#x1f50d; 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术&#xff0c;可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势&#xff0c;还能有效评价重大生态工程…...

leetcodeSQL解题:3564. 季节性销售分析

leetcodeSQL解题&#xff1a;3564. 季节性销售分析 题目&#xff1a; 表&#xff1a;sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...

用docker来安装部署freeswitch记录

今天刚才测试一个callcenter的项目&#xff0c;所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

AspectJ 在 Android 中的完整使用指南

一、环境配置&#xff08;Gradle 7.0 适配&#xff09; 1. 项目级 build.gradle // 注意&#xff1a;沪江插件已停更&#xff0c;推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...

ip子接口配置及删除

配置永久生效的子接口&#xff0c;2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...