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 注解的属性会被格式化