Java序列化JSON时long型数值,会出现精度丢失的问题。 原因: java中得long能表示的范围比js中number大,也就意味着部分数值在js中存不下(变成不准确的值).
解决办法一: 使用ToStringSerializer的注解,让系统序列化 时,保留相关精度
@JsonSerialize(using=ToStringSerializer.class) private Long createdBy;
上述方法需要在每个对象都配上该注解,此方法过于繁锁。
解决办法(二): 使用全局配置,将转换时实现自动ToStringSerializer序列化
package com.chitic.module.core.config; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.http.HttpMessageConverters; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.MediaType; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.List; import java.util.TimeZone; @Configuration public class JsonConfig { @Bean @ConditionalOnMissingBean(HttpMessageConverters.class) //仅在该注解规定的类不存在于 spring容器中时,使用该注解的config或者bean声明才会被实例化到容器中 public HttpMessageConverters fastJsonHttpMessageConverters() { MappingJackson2HttpMessageConverter jackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter(); ObjectMapper objectMapper = new ObjectMapper(); /** * 序列换成json时,将所有的long变成string * 因为js中得数字类型不能包含所有的java long值 */ SimpleModule simpleModule = new SimpleModule(); simpleModule.addSerializer(Long.class, ToStringSerializer.instance); simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance); objectMapper.registerModule(simpleModule); //json中多余的参数不报错,不想要可以改掉 objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); //设置全局的时间转化 SimpleDateFormat smt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); objectMapper.setDateFormat(smt); // objectMapper.setTimeZone(TimeZone.getTimeZone("GMT+8"));//解决时区差8小时问题 // objectMapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() { // @Override // public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { // jsonGenerator.writeObject(""); // } // }); //设置中文编码格式 List<MediaType> list = new ArrayList<>(); list.add(MediaType.APPLICATION_JSON_UTF8); jackson2HttpMessageConverter.setSupportedMediaTypes(list); jackson2HttpMessageConverter.setObjectMapper(objectMapper); return new HttpMessageConverters((HttpMessageConverter<?>) jackson2HttpMessageConverter); } }
方法二比较完美,强烈推荐使用!
后台date类型,而返回到前段为long(如后端yyy-mm-dd hh:mm:ss 返回前段为1562566384)
1.在实体类中在要转换的字段上加上该注解,如下:
/** 订单创建时间 */ @JsonSerialize(using = DateToLongSerializer.class) private Date createTiem;
2.并指定一个格式化的类。如下:
public class DateToLongSerializer extends JsonSerializer<Date> { @Override public void serialize(Date date, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { jsonGenerator.writeNumber(date.getTime() / 1000); } }
@JsonIgnore 该注解的作用是转成json时不返回给前端