学无先后,达者为师

网站首页 前端文档 正文

JSON转Long类型时精度丢失问题解决

作者:ImisLi 更新时间: 2024-03-25 前端文档

这个问题的原因是js在对长整型数据进行处理时会损失精度, 从而id发生变化。

要想解决这个问题,也很简单,只需要让js处理的ID数据类型为字符串类型即可, 这样就不会损失精度了

问题修复

1、JacksonObjectMapper

reggie-common模块下创建com.itheima.reggie.common.JacksonObjectMapper,自定义映射规则


import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.DateSerializer;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;

import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.util.Date;

import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES;

/**
 * 对象映射器:基于jackson将Java对象转为json,或者将json转为Java对象
 * 将JSON解析为Java对象的过程称为 [从JSON反序列化Java对象]
 * 从Java对象生成JSON的过程称为 [序列化Java对象到JSON]
 */
public class JacksonObjectMapper extends ObjectMapper {
    public JacksonObjectMapper() {
        super();
        //收到未知属性时不报异常
        this.configure(FAIL_ON_UNKNOWN_PROPERTIES, false);

        //反序列化时,属性不存在的兼容处理
        this.getDeserializationConfig().withoutFeatures(FAIL_ON_UNKNOWN_PROPERTIES);

        //自定义转换规则
        SimpleModule simpleModule = new SimpleModule()
                .addSerializer(BigInteger.class, ToStringSerializer.instance)//将BigInteger转换为String
                .addSerializer(Long.class, ToStringSerializer.instance);//将Long转换成String
        this.registerModule(simpleModule);
    }
}

或是:将其存入springbean中 即 加一个 @Component


import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import org.springframework.stereotype.Component;

import java.math.BigInteger;

import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES;

@Component
public class JacksonObjectMapper extends ObjectMapper {
    public JacksonObjectMapper() {
        super();
        //收到未知属性时不报异常
        this.configure(FAIL_ON_UNKNOWN_PROPERTIES, false);

        //反序列化时,属性不存在的兼容处理
        this.getDeserializationConfig().withoutFeatures(FAIL_ON_UNKNOWN_PROPERTIES);

        //自定义转换规则
        SimpleModule simpleModule = new SimpleModule()
                .addSerializer(BigInteger.class, ToStringSerializer.instance)//将BigInteger转换为String
                .addSerializer(Long.class, ToStringSerializer.instance);//将Long转换成String
        this.registerModule(simpleModule);
    }
}

 

2、WebMvcConfig

com.itheima.reggie.config.ReggieWebMvcConfig中添加下面代码  

 //扩展mvc框架的消息转换器
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        //创建消息转换器对象
        MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();
        //设置对象转换器,底层使用Jackson将Java对象转为json
        messageConverter.setObjectMapper(new JacksonObjectMapper());
        //将上面的消息转换器对象追加到mvc框架的转换器集合中
        converters.add(0, messageConverter);
    }

完整的WebMvcConfig类的代码:

package com.itheima.reggie.config;

import com.itheima.reggie.common.JacksonObjectMapper;
import com.itheima.reggie.interceptors.CheckLoginInterceptors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName ReggieWebManageWebConfigurer
 * @Description 后台管理的webmvc的配置类
 * @Author LPS
 * @Date 2023/7/31 21:51
 */
@Configuration
public class ReggieWebManageWebConfigurer implements WebMvcConfigurer {

    //登录拦截器
    @Autowired
    private CheckLoginInterceptors checkLoginInterceptors;
    /**
     * 指定静态资源加载位置
     * @param registry
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        //当访问请求是/backend/**时,去classpath:/backend/寻找对应资源
        // Handler --相当-- 前端路径 ,Locations --相当-- 后端加载
        //Resource  资源
        registry.addResourceHandler("/backend/**").addResourceLocations("classpath:/backend/");
    }

    /*注册拦截器*/
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        List<String> stringList = new ArrayList<>();
        stringList.add("/employee/login");
        stringList.add("/employee/logout");
        stringList.add("/backend/**");
        stringList.add("/error");
        registry.addInterceptor(checkLoginInterceptors)  // 将拦截器添加到拦截列表
                .addPathPatterns("/**")   // 需要拦截的路径  这里是拦截所有
                .excludePathPatterns(stringList);  // 需要放行的路径
    }

    //扩展mvc框架的消息转换器
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        //创建消息转换器对象
        MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();
        //设置对象转换器,底层使用Jackson将Java对象转为json
        messageConverter.setObjectMapper(new JacksonObjectMapper());
        //将上面的消息转换器对象追加到mvc框架的转换器集合中
        converters.add(0, messageConverter);
    }
}

或是:



import com.itheima.reggie.common.JacksonObjectMapper;
import com.itheima.reggie.interceptors.CheckLoginInterceptors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.ArrayList;
import java.util.List;

@Configuration
public class ReggieWebManageWebConfigurer implements WebMvcConfigurer {

    @Autowired
    private CheckLoginInterceptors checkLoginInterceptors;

    /**
     * 指定静态资源加载位置
     *
     * @param registry
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        //当访问请求是/backend/**时,去classpath:/backend/寻找对应资源
        // Handler --相当-- 前端路径 ,Locations --相当-- 后端加载
        //Resource  资源
        registry.addResourceHandler("/backend/**").addResourceLocations("classpath:/backend/");
    }

    /*注册拦截器*/
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        List<String> stringList = new ArrayList<>();
        stringList.add("/employee/login");
        stringList.add("/employee/logout");
        stringList.add("/backend/**");
        stringList.add("/error");
        registry.addInterceptor(checkLoginInterceptors)  // 将拦截器添加到拦截列表
                .addPathPatterns("/**")   // 需要拦截的路径  这里是拦截所有
                .excludePathPatterns(stringList);  // 需要放行的路径
    }

    //  自定义数据类型转换器
    @Autowired
    private JacksonObjectMapper jacksonObjectMapper;

    //扩展mvc框架的消息转换器
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        //创建消息转换器对象
        MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();
        //设置对象转换器,底层使用Jackson将Java对象转为json
        messageConverter.setObjectMapper(jacksonObjectMapper);
        //将上面的消息转换器对象追加到mvc框架的转换器集合中
        converters.add(0, messageConverter);
    }
}

 

原文链接:https://blog.csdn.net/ImisLi/article/details/132156735

  • 上一篇:没有了
  • 下一篇:没有了
栏目分类
最近更新