一.抛出问题:

  现在的项目中,存在这样的几个问题:

    问题一.数据库存的数据类型是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 处理后端返回的小数(全局配置 + 定制化配置)的更多相关文章

  1. SpringBoot 如何统一后端返回格式?老鸟们都是这样玩的!

    大家好,我是飘渺. 今天我们来聊一聊在基于SpringBoot前后端分离开发模式下,如何友好的返回统一的标准格式以及如何优雅的处理全局异常. 首先我们来看看为什么要返回统一的标准格式? 为什么要对Sp ...

  2. SpringBoot 如何统一后端返回格式

    在前后端分离的项目中后端返回的格式一定要友好,不然会对前端的开发人员带来很多的工作量.那么SpringBoot如何做到统一的后端返回格式呢?今天我们一起来看看. 为什么要对SpringBoot返回统一 ...

  3. SpringBoot项目中处理返回json的null值

    在后端数据接口项目开发中,经常遇到返回的数据中有null值,导致前端需要进行判断处理,否则容易出现undefined的情况,如何便捷的将null值转换为空字符串? 以SpringBoot项目为例,SS ...

  4. Vue Springboot (包括后端解决跨域)实现登录验证码功能详细完整版

    利用Hutool 基于Vue.ElementUI.Springboot (跨域)实现登录验证码功能 前言 一.Hutool是什么? 二.下面开始步入正题:使用步骤 1.先引入Hutool依赖 2.控制 ...

  5. Springboot+vue前后端分离项目,poi导出excel提供用户下载的解决方案

    因为我们做的是前后端分离项目 无法采用response.write直接将文件流写出 我们采用阿里云oss 进行保存 再返回的结果对象里面保存我们的文件地址 废话不多说,上代码 Springboot 第 ...

  6. springboot+apache前后端分离部署https

    目录 1. 引言 2. 了解https.证书.openssl及keytool 2.1 https 2.1.1 什么是https 2.1.2 https解决什么问题 2.2 证书 2.2.1 证书内容 ...

  7. SpringBoot+Vue前后端分离,使用SpringSecurity完美处理权限问题

    原文链接:https://segmentfault.com/a/1190000012879279 当前后端分离时,权限问题的处理也和我们传统的处理方式有一点差异.笔者前几天刚好在负责一个项目的权限管理 ...

  8. SpringBoot+Vue 前后端合并部署

    前后端分离开发项目 前端vue项目 服务端springboot项目 如何将vue的静态资源整合到springboot项目里,通过启动jar包的方式部署服务. 前端项目执行npm run build 命 ...

  9. springboot配置server相关配置&整合模板引擎Freemarker、thymeleaf&thymeleaf基本用法&thymeleaf 获取项目路径 contextPath 与取session中信息

    1.Springboot配置server相关配置(包括默认tomcat的相关配置) 下面的配置也都是模板,需要的时候在application.properties配置即可 ############## ...

随机推荐

  1. jquery通过live绑定toggle事件

    $("a[name=reply]").live("click",function(){ $(this).toggle( function () { var $c ...

  2. dubbo-zookeeper quick start

    目录 dubbo快速开始 服务提供者(Service provider) 定义服务接口(Defining service interfaces) 在服务提供方实现接口(Implement interf ...

  3. bouncycastle中添加HMAC-SM3支持

    一. 最近看完了PKCS#5中的内容,总结一下自己添加HMAC-SM3中遇到的问题和解决方法. 大概通读BC java源码以后,开始上手修改. 在SM3.java中添加如下代码: /** * SM3 ...

  4. windows跳转端口

    //将客户机端口内网33306转发到外网,在通过本地连接ssh -L 3306:10.0.0.208:3306 ttx@180.180.180.182--通过git bash执行命令--10.0.0. ...

  5. Java标识符,关键字,保留字三者区分(主要是从官网摘抄)

    区分 标识符(Identifiers) An identifier is an unlimited-length sequence of Java letters and Java digits, t ...

  6. Android的Proxy/Delegate Application框架

    转自:http://blogs.360.cn/360mobile/2013/11/25/proxydelegate-application/#comment-77 有的时候,为了实现一些特殊需求,如界 ...

  7. BZOJ_1503 [NOI2004]郁闷的出纳员 【Splay树】

    一 题面 [NOI2004]郁闷的出纳员 二 分析 模板题. 对于全部员工的涨工资和跌工资,可以设一个变量存储起来,然后在进行删除时,利用伸展树能把结点旋转到根的特性,能够很方便的删除那些不符合值的点 ...

  8. Python-tkinter-window

    示例代码讲解 1.加载tkinter模块 2.创建一个窗口 3.设置窗口的主题 4.开始窗口的事件循环 import tkinter 2 win = tkinter.Tk() 3 win.title( ...

  9. linux库文件编程

    参考博文链接: https://www.cnblogs.com/guochaoxxl/p/7141447.html https://www.cnblogs.com/tuhooo/p/8757192.h ...

  10. 第28 章 : 理解容器运行时接口 CRI

    理解容器运行时接口 CRI CRI 是 Kubernetes 体系中跟容器打交道的一个非常重要的部分.本文将主要分享以下三方面的内容: CRI 介绍 CRI 实现 相关工具 CRI 介绍 在 CRI ...