【SpringBoot】SpringBoot 处理后端返回的小数(全局配置 + 定制化配置)
一.抛出问题:
现在的项目中,存在这样的几个问题:
问题一.数据库存的数据类型是BigDecimal,或者代码中计算需要返回BigDecimal的值,由于BigDecimal返回给前端可能存在精度丢失情况
问题二.BigDecimal再后台计算后,通常需要保留两位小数或者三位小数返回给前端,每个数据都需要处理,代码太过于冗余;
二.解决方式:
问题一的解决方案:
使用全局的序列化配置,统一将BigDecimal的数据类型转换为String类型,前端将String解析为小数即可;
代码如下
package com.gabriel.stage.config; 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.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import com.google.common.collect.ImmutableList;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.List; /**
* @author Gabriel
* @date 2020-01-08
* @description 自定义SpringMvc转换器 解决数据转换问题(例如BigDecimal转换为String,解决精度问题)
* 注意:springboot2.x以后继承 WebMvcConfigurationSupport 会覆盖"所有的WebMvc默认的配置,比如WebMvcConfigure",因此不推荐该中方法
*/
//@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport { /**
* Date格式化字符串
*/
private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd");
/**
* DateTime格式化字符串
*/
private static final DateTimeFormatter DATETIME_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
/**
* Time格式化字符串
*/
private static final DateTimeFormatter TIME_FORMAT = DateTimeFormatter.ofPattern("HH:mm:ss"); @Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
super.configureMessageConverters(converters);
final MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
ObjectMapper objectMapper = converter.getObjectMapper(); // 反序列化失败
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); // long 转换为字符串
SimpleModule simpleModule = new SimpleModule();
simpleModule.addSerializer(BigInteger.class, ToStringSerializer.instance);
simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance); // 浮点型使用字符串
simpleModule.addSerializer(Double.class, ToStringSerializer.instance);
simpleModule.addSerializer(Double.TYPE, ToStringSerializer.instance);
simpleModule.addSerializer(BigDecimal.class, ToStringSerializer.instance); // java8 时间格式化
simpleModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DATETIME_FORMAT));
simpleModule.addSerializer(LocalDate.class, new LocalDateSerializer(DATE_FORMAT));
simpleModule.addSerializer(LocalTime.class, new LocalTimeSerializer(TIME_FORMAT)); objectMapper.registerModule(simpleModule); // 为mapper注册一个带有SerializerModifier的Factory,处理null值
objectMapper.setSerializerFactory(objectMapper.getSerializerFactory()
//CustomizeBeanSerializerModifier 自定义序列化修改器
.withSerializerModifier(new CustomizeBeanSerializerModifier())); // 处理中文乱码问题
converter.setSupportedMediaTypes(ImmutableList.of(MediaType.APPLICATION_JSON_UTF8)); converter.setObjectMapper(objectMapper);
converters.add(converter);
converters.add(new StringHttpMessageConverter(StandardCharsets.UTF_8));
}
}
问题二的解决方案:
自定义序列器,使用 @JsonSerialize(using = 自定义序列化器类.class)去序列化指定的属性
代码如下
package com.in.g.data.config; import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider; import java.io.IOException;
import java.math.BigDecimal; /**
* @author: Gabriel
* @date: 2020/3/7 15:28
* @description 小数保留2位返回给前端序列化器
*/
public class Decimal2Serializer extends JsonSerializer<Object> { /**
* 将返回的BigDecimal保留两位小数,再返回给前端
* @param value
* @param jsonGenerator
* @param serializerProvider
* @throws IOException
* @throws JsonProcessingException
*/
@Override
public void serialize(Object value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
if (value != null) {
BigDecimal bigDecimal = new BigDecimal(value.toString()).setScale(2,BigDecimal.ROUND_HALF_UP);
jsonGenerator.writeString(bigDecimal.toString());
}
}
}
package com.gabriel.stage.vo; import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.gabriel.stage.config.Decimal2Serializer;
import lombok.Data; import java.math.BigDecimal; /**
* @author: Gabriel
* @date: 2020/3/7 15:45
* @description
*/
@Data
public class TestVO { @JsonSerialize(using = Decimal2Serializer.class)
private BigDecimal bigDecimal;
}
【SpringBoot】SpringBoot 处理后端返回的小数(全局配置 + 定制化配置)的更多相关文章
- SpringBoot 如何统一后端返回格式?老鸟们都是这样玩的!
大家好,我是飘渺. 今天我们来聊一聊在基于SpringBoot前后端分离开发模式下,如何友好的返回统一的标准格式以及如何优雅的处理全局异常. 首先我们来看看为什么要返回统一的标准格式? 为什么要对Sp ...
- SpringBoot 如何统一后端返回格式
在前后端分离的项目中后端返回的格式一定要友好,不然会对前端的开发人员带来很多的工作量.那么SpringBoot如何做到统一的后端返回格式呢?今天我们一起来看看. 为什么要对SpringBoot返回统一 ...
- SpringBoot项目中处理返回json的null值
在后端数据接口项目开发中,经常遇到返回的数据中有null值,导致前端需要进行判断处理,否则容易出现undefined的情况,如何便捷的将null值转换为空字符串? 以SpringBoot项目为例,SS ...
- Vue Springboot (包括后端解决跨域)实现登录验证码功能详细完整版
利用Hutool 基于Vue.ElementUI.Springboot (跨域)实现登录验证码功能 前言 一.Hutool是什么? 二.下面开始步入正题:使用步骤 1.先引入Hutool依赖 2.控制 ...
- Springboot+vue前后端分离项目,poi导出excel提供用户下载的解决方案
因为我们做的是前后端分离项目 无法采用response.write直接将文件流写出 我们采用阿里云oss 进行保存 再返回的结果对象里面保存我们的文件地址 废话不多说,上代码 Springboot 第 ...
- springboot+apache前后端分离部署https
目录 1. 引言 2. 了解https.证书.openssl及keytool 2.1 https 2.1.1 什么是https 2.1.2 https解决什么问题 2.2 证书 2.2.1 证书内容 ...
- SpringBoot+Vue前后端分离,使用SpringSecurity完美处理权限问题
原文链接:https://segmentfault.com/a/1190000012879279 当前后端分离时,权限问题的处理也和我们传统的处理方式有一点差异.笔者前几天刚好在负责一个项目的权限管理 ...
- SpringBoot+Vue 前后端合并部署
前后端分离开发项目 前端vue项目 服务端springboot项目 如何将vue的静态资源整合到springboot项目里,通过启动jar包的方式部署服务. 前端项目执行npm run build 命 ...
- springboot配置server相关配置&整合模板引擎Freemarker、thymeleaf&thymeleaf基本用法&thymeleaf 获取项目路径 contextPath 与取session中信息
1.Springboot配置server相关配置(包括默认tomcat的相关配置) 下面的配置也都是模板,需要的时候在application.properties配置即可 ############## ...
随机推荐
- Java开发不懂Docker,学尽Java也枉然,阿里P8架构师手把手带你玩转Docker实战
转: Java开发不懂Docker,学尽Java也枉然,阿里P8架构师手把手带你玩转Docker实战 Docker简介 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一 ...
- OpenGL中的坐标系统详细概括:包括Z缓冲
一: 首先就是关于几个坐标系统的概括: 局部坐标是对象相对于局部原点的坐标,也是物体起始的坐标. 下一步是将局部坐标变换为世界空间坐标,世界空间坐标是处于一个更大的空间范围的.这些坐标相对于世界的全局 ...
- CVE-2020-1938 -Tomcat-AJP任意文件读取/包含
为什么这个漏洞被称作 Ghostcat(幽灵猫)? 这个漏洞影响全版本默认配置下的 Tomcat(在我们发现此漏洞的时候,确认其影响 Tomcat 9/8/7/6 全版本,而年代过于久远的更早的版本未 ...
- Java流程控制:用户交互Scanner
java.util.Scanner工具类获取用户输入语法:Scanner scanner = new Scanner(System.in);通过Scanner类的next()与nextLine()方法 ...
- MyBatis(七):MyBatis缓存详解(一级缓存/二级缓存)
一级缓存 MyBatis一级缓存上SqlSession缓存,即在统一SqlSession中,在不执行增删改操作提交事务的前提下,对同一条数据进行多次查询时,第一次查询从数据库中查询,完成后会存入缓 ...
- 从零学脚手架(五)---react、browserslist
如果此篇对您有所帮助,在此求一个star.项目地址: OrcasTeam/my-cli react react介绍 目前,国内主流的前端应用框架具有两个:vue.js和react.js,关于vue和r ...
- 记一次jstack命令定位问题
今天天气不错,但是赶上恶意加班心情就不爽,怀着不爽的心情干活,总能创造出更多的问题,这不,今天就自己挖了一个坑,自己跳进去了,好在上来了 经过是这样的,开始调试canal采集binlog时,由于添加了 ...
- .NET并发编程-任务函数并行
本系列学习在.NET中的并发并行编程模式,实战技巧 请问普通: 被门夹过的核桃还能补脑吗 本小节开始学习基于任务的函数式并行.本系列保证最少代码呈现量,虽然talk is cheap, show me ...
- 15款NOSQL数据库
1.MongoDB 介绍 MongoDB是一个基于分布式文件存储的数据库.由C++语言编写.主要解决的是海量数据的访问效率问题,为WEB应用提供可扩展的高性能数据存储解决方案.当数据量达到50GB以上 ...
- Nodejs学习笔记(5) 文件上传系统实例
目录 2018.8.4更新: MySQL可以存放几乎任何类型的数据(图片.文档.压缩包等),但这不是最好的解决方案,正常情况下都是在数据库中存放文件路径,图片.音乐.视频.压缩包.文档等文件存放在硬 ...