Springboot全局配置實(shí)現(xiàn)BigDecimal返回前端去除小數(shù)點(diǎn)后多余的零
一、前言
我們?cè)谑褂肂igDecimal來記錄數(shù)值時(shí),經(jīng)常會(huì)有一個(gè)問題,就是小數(shù)點(diǎn)后多余的0!
當(dāng)前如果你們是金額,保留兩位小數(shù),展示多余的0是沒有問題的!可以看一下銀行卡是會(huì)顯示到分的!
小編的這里不是這種的,是要求保留八位小數(shù),即使前端輸入100.1。保存到數(shù)據(jù)庫時(shí)就會(huì)變?yōu)椋?00.10000000,前端查詢出來肯定就是100.10000000。非常的臃腫,我們就需要去掉一下!
二、解決方案
分為兩種方案:
- 按需進(jìn)行去除0。
- 全局BigDecimal全部去除0。
各有各的優(yōu)缺點(diǎn),就是看你們系統(tǒng)的要求了!
小編這里是有的允許保留0的,不需要的咱們單獨(dú)處理。所以咱們先演示第一種!
1、第一種方案
「編寫自定義序列化器:BigDecimalSerializer」
/**
* BigDecimal序列化器
* @author wangzhenjun
* @date 2023/5/17 16:29
*/
public class BigDecimalSerializer extends JsonSerializer<BigDecimal> {
@SneakyThrows
@Override
public void serialize(BigDecimal bigDecimal, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) {
if (null != bigDecimal ) {
String plainString = bigDecimal.stripTrailingZeros().toPlainString();
jsonGenerator.writeString(plainString);
} else {
jsonGenerator.writeString(BigDecimal.ZERO.toPlainString());
}
}
}
在需要的對(duì)象上添加注解@JsonSerialize即可:
/**
* @author wangzhenjun
* @date 2023/5/17 16:51
*/
@Data
public class Big {
@JsonSerialize(using = BigDecimalSerializer.class)
private BigDecimal price;
}
測(cè)試一下:
@GetMapping("/big")
public Result big(){
Big big = new Big();
big.setPrice(new BigDecimal("1.20"));
return Result.success(big);
}
我們可以看到正常的去除多余的0,我們會(huì)發(fā)現(xiàn)原來的BigDecimal變?yōu)榱俗址鋵?shí)這個(gè)也是正常的,在我們系統(tǒng)里會(huì)配置上,把Long和BigDecimal返回前端的時(shí)候都會(huì)變?yōu)樽址?,防止精度丟失。
想詳細(xì)了解的可以看看文章,趕時(shí)間的,小編在下面給出來了,添加一個(gè)配置類即可!
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(ObjectMapper.class)
@AutoConfigureBefore(JacksonAutoConfiguration.class)
public class JacksonConfiguration {
@Bean
@ConditionalOnMissingBean
public Jackson2ObjectMapperBuilderCustomizer customizer() {
return builder -> {
builder.locale(Locale.CHINA);
builder.timeZone(TimeZone.getTimeZone(ZoneId.systemDefault()));
// 設(shè)置日期格式
builder.simpleDateFormat(DatePattern.NORM_DATETIME_PATTERN);
// 解決long類型損失精度
builder.serializerByType(Long.class, ToStringSerializer.instance);
// 解決BigDecimal類型損失精度
builder.serializerByType(BigDecimal.class, ToStringSerializer.instance);
// 日期格式自定義類
builder.modules(new PigJavaTimeModule());
};
}
}
2、第二種方式
我們只需要進(jìn)行序列化的時(shí)候去除一下即可,這是全局的BigDecimal都會(huì)去除多余0,大家按需使用,以免造成不必要的事故!
/**
* 全局序列化配置
* @author wangzhenjun
* @date 2023/5/19 17:11
*/
@Configuration
public class JacksonConfig {
@Bean
public ObjectMapper objectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addSerializer(BigDecimal.class, new JsonSerializer<BigDecimal>() {
@Override
public void serialize(BigDecimal value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
if (value != null) {
gen.writeString(value.stripTrailingZeros().toPlainString());
}
}
});
objectMapper.registerModule(module);
return objectMapper;
}
}
我們?cè)俅螠y(cè)試,我把上一種方式的寫法去掉了哈!
我們可以看到也是沒有問題的哈!
三、總結(jié)
通過本篇博客的介紹,我們知道了兩種解決方式!可以對(duì)BigDecimal類型進(jìn)行格式化,去除前端展示中多余的0。這樣能夠優(yōu)化前端展示效果,提高用戶體驗(yàn)。這個(gè)兩個(gè)方法都簡單易用,而且具有通用性,適合大部分項(xiàng)目使用。
當(dāng)然,在實(shí)際開發(fā)中,還有很多其他的格式化方式和技巧可以使用,比如使用前端框架的過濾器、使用JavaScript的toFixed()函數(shù)等等。不過,無論使用哪種方式,我們要做到的是盡可能地避免前端展示中出現(xiàn)多余的0,保證用戶體驗(yàn)。
最最重要的是符合業(yè)務(wù)要求!
希望本篇博客的介紹能夠?qū)Υ蠹矣兴鶐椭?/p>