Customize global serialization to serialize BigDecimal type to String type, and annotation to achieve serialization of BigDecimal type to String type

Solution 1: Customize global serialization

After the project went online, the product purchase failed because the price was incorrect at 30.495, but the database was 30.50.

  • Define the problem as BigDecimal loses precision
  • Serialize BigDecimal type data into String type and pass it to the front end to solve the problem. The front-end value let or var is not strongly typed.
    1. The custom serialization class inherits the StdSerializer class and re-serialize method
public class BigDecimalStringSerializer extends StdSerializer<BigDecimal> {
    
    

    public final static BigDecimalStringSerializer instance = new BigDecimalStringSerializer();

    public BigDecimalStringSerializer() {
    
    
        super(BigDecimal.class);
    }
    @Override
    public void serialize(BigDecimal value, JsonGenerator gen, SerializerProvider provider) throws IOException {
    
    
        if(value==null){
    
    
            gen.writeString("0");
        }else{
    
    
            String val=value.stripTrailingZeros().toPlainString();
            gen.writeString(val);
        }
    }


}

Two, configure global serialization

/**
 * Jackson配置类
 */
@Configuration
public class JacksonConfig {
    
    
    @Bean
    @Primary
    @ConditionalOnMissingBean(ObjectMapper.class)
    public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
    
    
        ObjectMapper objectMapper = builder.createXmlMapper(false).build();
        SimpleModule bigDecimalModule = new SimpleModule();
        //序列化将BigDecimal转String类型
        bigDecimalModule.addSerializer(BigDecimal.class, BigDecimalStringSerializer.instance);
        bigDecimalModule.addKeySerializer(BigDecimal.class, BigDecimalStringSerializer.instance);
        // 注册转换器
        objectMapper.registerModule(bigDecimalModule);
//        json不返回null的字段
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        return objectMapper;
    }
}

Three, test
Create entity classes for testing

@Data
public class UserDetail {
    
    
    private BigDecimal price;
    private String phone;
    }
@GetMapping("/user/detail")
    public UserDetail userdetail(){
    
    
        return new UserDetail(BigDecimal.valueOf(2L),"12345");
    }
  • After this configuration is String type
    Insert picture description here

Solution 2: Add annotation @JsonSerialize(using= ToStringSerializer.class)

Directly add the annotation @JsonSerialize(using = ToStringSerializer.class) to the field of BBigDecimal type

@JsonSerialize(using= ToStringSerializer.class)
    private BigDecimal price;
  • The effect is the same, but the disadvantage is that each BigDecimal type attribute needs to add this annotation.

Guess you like

Origin blog.csdn.net/weixin_45528650/article/details/112256534