SpringBoot自定义Jackson注解,实现自定义序列化BigDecimal(增强JsonFormat注解)

文章目录

    • 需求背景
    • 代码
    • 如何使用
    • 小结

需求背景

在处理BigDecimal字段的时候,希望自定义序列化格式。虽然有 JsonFormat可以自定义格式,但是还是不够,JsonFormat不能对 BigDecimal 进行个性化处理,比如指定的RoundingMode。 现在就是需要有个注解,可以实现自定序列化BigDecimal类型

代码

首先,自定义一个注解 BigDecimalFormatter

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@JacksonAnnotationsInside
@Documented
public @interface BigDecimalFormatter {

    String pattern() default "###.##";

    JsonFormat.Shape shape() default JsonFormat.Shape.NUMBER;

    int newScale() default 2;

    RoundingMode roundingMode() default RoundingMode.HALF_UP;

}

实现一个 JsonSerializer ,可以参考Jackson的内置的一些Serializer。 我们这里直接集成 StdSerializer

/**
 * @author jianyang.liu
 * @date 8/7/2023 3:43 PM
 */
@JsonComponent
public class BigDecimalSerializer extends StdSerializer<BigDecimal> implements ContextualSerializer {

    private  String pattern;

    private  JsonFormat.Shape shape;

    private  int newScale;

    private  RoundingMode roundingMode;


    public BigDecimalSerializer(){
        super(BigDecimal.class);
    }

    public BigDecimalSerializer(BigDecimalFormatter annotation){
        super(BigDecimal.class);
        this.pattern = annotation.pattern();
        this.shape = annotation.shape();
        this.newScale = annotation.newScale();
        this.roundingMode = annotation.roundingMode();
    }


    @Override
    public void serialize(BigDecimal value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {

        if (shape == JsonFormat.Shape.STRING){
            String output = null;
            if (value != null) {
                output = new DecimalFormat(pattern).format(value);
            }
            jsonGenerator.writeString(output);
        }else{
            BigDecimal output = value.setScale(newScale, roundingMode);
            jsonGenerator.writeNumber(output);
        }

    }


    @Override
    public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty beanProperty) {
        AnnotatedMember member = beanProperty.getMember();
        BigDecimalFormatter annotation = member.getAnnotation(BigDecimalFormatter.class);
        if (annotation != null){
            return new BigDecimalSerializer(annotation);
        }
        return NumberSerializer.instance;
    }
}

说明: @JsonComponent 注解 是SpringBoot的一个注解,是为了方便将自定义的Jackson配置 有了这个注解,就不需要手动添加到 ObjectMapper 的配置中去了

如何使用

提示:这里可以添加技术名词解释

public class TestDemo{


	@BigDecimalFormatter(shape = JsonFormat.Shape.NUMBER,newScale = 4,roundingMode = RoundingMode.HALF_UP)
    private BigDecimal value;
    
    @BigDecimalFormatter(shape = JsonFormat.Shape.STRING,pattern = "###.##")
    private BigDecimal value2;

}

小结

通过这个注解,就可以很方便的实现对Bigdecimal的格式化控制,shape = JsonFormat.Shape.STRING 返回的json数据会是字符串类型,也就是说值会带引号,这一点需要注意。

你可能感兴趣的:(Java,日常解决问题,SpringBoot,spring,boot,后端,java,jackson)