BigDecimal格式化 自定义注解

3,229 阅读1分钟

1.依赖添加(如果已经有了对应依赖 无序添加)

  compile "com.fasterxml.jackson.core:jackson-databind:2.9.9.3" 

2.格式化策略枚举 定义

/**
 * @desc: BigDecimal格式化策略
 * @author: tianpanke
 * @create: 2019-12-12 10:20
 **/
public enum BigDecimalFormatPolicy {
   ROUND_HALF_UP(1,"四舍五入"),
   ROUND_CUT_TAIL(2,"截尾");
    private Integer value;
    private String text;
    BigDecimalFormatPolicy(Integer value,String text){
        this.value=value;
        this.text=text;
    }

    public Integer getValue() {
        return value;
    }
}

3.数据转换类型枚举定义

public enum BigDecimalFormatType {
    TO_NUMBER_TYPE(1,"转Number类型"),
    TO_STRING_TYPE(2,"转String类型")
    ;
    private Integer value;
    private String text;
    BigDecimalFormatType(Integer value,String text){
        this.value=value;
        this.text=text;
    }
    public Integer getValue() {
        return value;
    }
    public String getText() {
        return text;
    }

}

4.格式化注解定义

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 {
    String pattern() default "0.00";
    BigDecimalFormatPolicy policy() default  BigDecimalFormatPolicy.ROUND_HALF_UP;
    BigDecimalFormatType type() default BigDecimalFormatType.TO_STRING_TYPE;
}

5.序列化器定义

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 java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.Objects;

/**
 * @descri: BigDecimal序列化
 * @author: tianpanke
 * @create: 2019-12-12 10:08
 **/
public class BigDecimalSerializer extends JsonSerializer implements ContextualSerializer {
    private String  pattern; //格式化 模式
    private BigDecimalFormatPolicy formatPolicy;//默认 截尾
    private BigDecimalFormatType toType;
    @Override
    public void serialize(BigDecimal value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        if(value!=null){
            RoundingMode roundingMode=(formatPolicy==BigDecimalFormatPolicy.ROUND_HALF_UP)?RoundingMode.HALF_UP:RoundingMode.DOWN;
            DecimalFormat decimalFormat=new DecimalFormat(pattern);
            decimalFormat.setRoundingMode(roundingMode);
            String formatResult=decimalFormat.format(value);
            if(toType==BigDecimalFormatType.TO_NUMBER_TYPE) gen.writeNumber(formatResult); else gen.writeString(formatResult);
        }else{
            gen.writeNumber(value);
        }
    }

    @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.pattern = bigDecimalFormat.pattern();
                    bigDecimalSerializer.formatPolicy= bigDecimalFormat.policy();
                    bigDecimalSerializer.toType= bigDecimalFormat.type();
                }
                return bigDecimalSerializer;
            }
            return serializerProvider.findValueSerializer(beanProperty.getType(),beanProperty);
        }
        return serializerProvider.findNullValueSerializer(beanProperty);
    }
}

6.使用方法

直接在要响应给前端的DTO的Bigdecimal类型的字段上,加上@BigdecimalFormat注解即可(默认保留两位小数,四舍五入,转为String);当然可以根据自己的需要传参。