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時不返回給前端