后端传输前段Long类型太长,而Java序列化JSON丢失精度的问题

被刻印的时光 ゝ 提交于 2020-05-02 06:14:06

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时不返回给前端

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!