SpringBoot 转 Json 对 BigDecimal 格式化

SpringBoot 转 Json 对 BigDecimal 格式化

——SpringBoot 返回对象自动转 Json 时对 BigDecimal 格式化

先说全局配置;
最后说怎样局部配置 (去掉两个注解就行);

——感谢原文: https://www.jianshu.com/p/db07543ffe0a

经过一番操作, 可以达到下面的效果
public class Example{
    
    // 不加 @BigDecimalFormat 注解, 在输出后转为 1.23
    private BigDecimal decimal1 = new BigDecimal("1.23456789");
    
    // 加 @BigDecimalFormat 注解, 在输出后转为 BigDecimalFormat 注解的默认值规定的格式 1.235
    @BigDecimalFormat
    private BigDecimal decimal2 = new BigDecimal("1.23456789");
    
    // 加 @BigDecimalFormat 注解且指定 value, 在输出后转为指定格式 1.2346
    @BigDecimalFormat("#.0000")
    private BigDecimal decimal3 = new BigDecimal("1.23456789");
    
    // constructors, setters, getters
    // ...
}
Serializer 类
package com.xxx;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import org.springframework.boot.jackson.JsonComponent;

import java.io.IOException;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.Objects;

@JsonComponent
public class BigDecimalSerializer extends JsonSerializer<BigDecimal> implements ContextualSerializer {

    // 默认格式化方案, 项目中添加了 BigDecimal 的格式化配置后, 
    // 所有未添加 @BigDecimalFormat 注解的 BigDecimal 数据都会变成这个格式;
    private String format = "#.00";

    @Override
    public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty beanProperty) throws JsonMappingException {
        if(beanProperty !=null ){
            if(Objects.equals(beanProperty.getType().getRawClass(),BigDecimal.class)){
                BigDecimalFormat bigDecimalFormat = beanProperty.getAnnotation((BigDecimalFormat.class));
                if(bigDecimalFormat == null){
                    bigDecimalFormat = beanProperty.getContextAnnotation(BigDecimalFormat.class);
                }
                BigDecimalSerializer bigDecimalSerializer = new BigDecimalSerializer();
                if(bigDecimalFormat != null){
                    bigDecimalSerializer.format = bigDecimalFormat.value();
                }
                return bigDecimalSerializer;
            }
            return serializerProvider.findValueSerializer(beanProperty.getType(),beanProperty);
        }
        return serializerProvider.findNullValueSerializer(beanProperty);
    }

    @Override
    public void serialize(BigDecimal bigDecimal, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        jsonGenerator.writeString(new DecimalFormat(format).format(bigDecimal));
    }
}

DeSerializer 类
package com.xxx;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import org.springframework.boot.jackson.JsonComponent;

import java.io.IOException;
import java.math.BigDecimal;

@JsonComponent
public class BigDecimalDeSerializer extends JsonDeserializer<BigDecimal> {
    @Override
    public BigDecimal deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {

        // 千分位分隔的数值从前端到后端是需要反序列化为BigDecimal。需要去掉“,”
        // return new BigDecimal(jsonParser.getText().replaceAll(",", ""));

        // 上面的代码是 copy 过来的, 原本是用于解析 #,###.000 这样的字符串, 本项目的场景暂时不需要
        return new BigDecimal(jsonParser.getText());
    }
}

自定义注解
package com.xxx;

import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@JacksonAnnotationsInside
@JsonSerialize(using = BigDecimalSerializer.class)
@JsonDeserialize(using = BigDecimalDeSerializer.class)
public @interface BigDecimalFormat {
    // 默认值, 凡是加了 @BigDecimalFormat 注解, 又没有指定 value 值的, 都会被格式化为下面的形式
    String value() default "#.000";
}

局部格式化配置

去掉 DeSerializer 类 和 Serializer 类上的 @JsonComponent 注解;

则只有加了 @BigDecimalFormat 注解的属性会被格式化

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值