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

基于Jackson自定义json数据的对象转换器

1、问题说明

后端数据表定义的id主键是Long类型,一共有20多位。 前端在接收到后端返回的json数据时,Long类型会默认当做数值类型进行处理。但前端处理20多位的数值会造成精度丢失,于是导致前端查询数据出现问题。 

  • 测试前端Long类型的代码

  • 实际显示效果

2、解决方法

在SpringBoot项目中,默认使用Jackson 来序列化和反序列化 json数据,针对上面的问题,决定采用自定义对象转换器的方式,在后端将数据转为json数据时,将Long类型的数据,统一转换为String类型,再转为json数据返回,避免前端处理Long类型数据造成精度丢失。

3、具体代码实现

在将controller层的返回值数据转为json数据时,需要经过消息转换器MappingJackson2HttpMessageConverter的处理。因此,只需要在消息转换器中判断如果是Long类型的数据,就转换为String类型,再进行json数据的转换。 在代码中,只需要重写extendMessageConverters()方法,添加自定义的对象转换器即可。

1) 编写JacksonObjectMapper对象转换器

该自定义的对象转换器, 主要指定了在进行json数据序列化及反序列化时, LocalDateTime、LocalDate、LocalTime的处理方式,以及BigInteger和Long类型数据,在序列化时直接转换为字符串。

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import java.math.BigInteger;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES;/*** 对象映射器:基于jackson将Java对象转为json,或者将json转为Java对象* 将JSON解析为Java对象的过程称为 [从JSON反序列化Java对象]* 从Java对象生成JSON的过程称为 [序列化Java对象到JSON]*/
public class JacksonObjectMapper extends ObjectMapper {public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";public JacksonObjectMapper() {super();//收到未知属性时不报异常this.configure(FAIL_ON_UNKNOWN_PROPERTIES, false);//反序列化时,属性不存在的兼容处理this.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);SimpleModule simpleModule = new SimpleModule()// 反序列化时的处理 .addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT))).addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT))).addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)))// 序列化时的处理 // 处理 BigInteger 类型.addSerializer(BigInteger.class, ToStringSerializer.instance)// 处理 Long 类型.addSerializer(Long.class, ToStringSerializer.instance).addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT))).addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT))).addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));//注册功能模块,添加自定义序列化与反序列化器this.registerModule(simpleModule);}
}

2)在WebMvcConfig中重写方法extendMessageConverters,添加自定义对象转换器


import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.List;@Configuration
@Slf4j
public class WebMvcConfig implements WebMvcConfigurer {/*** 扩展mvc框架的消息转换器* @param converters*/@Overridepublic void extendMessageConverters(List<HttpMessageConverter<?>> converters) {log.info("扩展消息转换器...");//创建消息转换器对象MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();//设置对象转换器,底层使用Jackson将Java对象转为jsonmessageConverter.setObjectMapper(new JacksonObjectMapper());//将上面的消息转换器对象追加到mvc框架的转换器集合中converters.add(0,messageConverter);}
}

4、测试

@RestController
public class TestController {@GetMapping("/test")public Map test(){Map<String, Object> map = new HashMap<>();map.put("name", "张三");map.put("age", 18L);return map;}}
  • 不添加转换器

  • 添加转换器

http://www.lryc.cn/news/277326.html

相关文章:

  • 【Java】缓存击穿解决方案
  • 【HarmonyOS】掌握 Stage 模型的核心概念与应用
  • 2024年甘肃省职业院校技能大赛 “信息安全管理与评估”赛项样题卷①
  • 我的AI之旅开始了
  • Day25 235二叉搜索树的公共祖先 701二叉搜索树插入 450二叉搜索树删除
  • android系列-init 挂载文件系统
  • Spring 七种事务传播性介绍
  • Count the Colors ZOJ - 1610
  • MATLAB点云处理总目录
  • C语言逗号表达式如何计算
  • Ubuntu 本地部署 ChatGPT-Next-Web
  • 小程序商城搭建:快速入门指南
  • c# windows10大小端试
  • 【算法专题】动态规划之斐波那契数列模型
  • K2P路由器刷OpenWrt官方最新版本固件OpenWrt 23.05.2方法 其他型号的智能路由器OpenWrt固件刷入方法也基本上适用
  • AI大语言模型会带来了新一波人工智能浪潮?
  • How to view the high-tech zone atmospheric project
  • sqlalchemy 中的缓存机制解释
  • 网络安全B模块(笔记详解)- 漏洞扫描与利用
  • 【C语言】指针——从底层原理到应用
  • 想了解步进伺服的朋友可以了解下这个方案
  • 航天航空线束工艺3D虚拟展馆支持多人异地参观漫游
  • JAVA面向对象基础-容器
  • 2022年山东省职业院校技能大赛高职组信息安全管理与评估—开发测试服务器解析
  • 2024年我国网络安全发展形势展望
  • 如何使用 NFTScan NFT API 在 PlatON 网络上开发 Web3 应用
  • 如何使用web文件管理器Net2FTP搭建个人网盘
  • 总结多线程的各种锁
  • 树形结构的窗口小部件
  • 【现代密码学】笔记3.1-3.3 --规约证明、伪随机性《introduction to modern cryphtography》