springboot的Long 前后端交互失去精度, BigDecimal序列化 精度问题,为空字段不序列化问题
方案1:为空字段序列化(always) application.yml配置 为空字段不序列化(non_null)
spring:
jackson:
default-property-inclusion: always
generator:
WRITE_NUMBERS_AS_STRINGS: true #所有数字转成字符串输出(虽然可以解决long和 BigDecimal精度丢失,但一般不用)
2: 解决BigDecimal序列化 精度问题
import com.fasterxml.jackson.core.JsonGenerator;
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 com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import org.springframework.boot.jackson.JsonComponent;
import java.io.IOException;
import java.math.BigDecimal;
/**
* @author zsd
* @version 1.0
* @date 2020/10/29 10:55
*/
@JsonComponent
public class BigDecimalJsonComponent {
public static class BigDecimalJsonSerializer extends JsonSerializer<BigDecimal> {
@Override
public void serialize(BigDecimal decimal, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
if (decimal!=null) {
jsonGenerator.writeString(decimal.setScale(2,BigDecimal.ROUND_HALF_UP).toString());
}
}
}
public static class BigDecimalJsonDeserializer extends JsonDeserializer<BigDecimal> {
@Override
public BigDecimal deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
return null;
}
}
}`
3: 解决BigDecimal序列化 精度问题
/**
* BigDecimal Long 转化为String
* @return
*/
@Bean
public MappingJackson2HttpMessageConverter toStringConverter() {
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
ObjectMapper mapper = new ObjectMapper();
SimpleModule simpleModule = new SimpleModule();
simpleModule.addSerializer(BigDecimal.class, BigDecimalToStringSerializer.instance);
simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
simpleModule.addSerializer(long.class, ToStringSerializer.instance);
mapper.registerModule(simpleModule);
converter.setObjectMapper(mapper);
return converter;
}
@JacksonStdImpl
static class BigDecimalToStringSerializer extends ToStringSerializer {
public final static BigDecimalToStringSerializer instance = new BigDecimalToStringSerializer();
public BigDecimalToStringSerializer() {
super(Object.class);
}
public BigDecimalToStringSerializer(Class<?> handledType) {
super(handledType);
}
@Override
public boolean isEmpty(SerializerProvider prov, Object value) {
if (value == null) {
return true;
}
String str = ((BigDecimal) value).stripTrailingZeros().toPlainString();
return str.isEmpty();
}
@Override
public void serialize(Object value, JsonGenerator gen, SerializerProvider provider)
throws IOException {
gen.writeString(((BigDecimal) value).stripTrailingZeros().toPlainString());
}
@Override
public JsonNode getSchema(SerializerProvider provider, Type typeHint) throws JsonMappingException {
return createSchemaNode("string", true);
}
@Override
public void serializeWithType(Object value, JsonGenerator gen,
SerializerProvider provider, TypeSerializer typeSer)
throws IOException {
// no type info, just regular serialization
serialize(value, gen, provider);
}
}
}