文章目录
- 需求背景
- 代码
- 如何使用
- 小结
需求背景
在处理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
* @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 = 返回的json数据会是字符串类型,也就是说值会带引号,这一点需要注意。