HttpMessageConverters 后端傳輸前段Long類型太長,而Java序列化JSON丟失精度的問題


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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM