1、前言

对于Long 类型的数据,如果我们在Controller层通过@ResponseBody将返回数据自动转换成json时,不做任何处理,而直接传给前端的话,在Long长度大于17位时会出现精度丢失的问题。

至于为啥丢失,我们在此处不探讨。

如图所示:后端返回数据如下:

而前端接收的数据时就丢失了精度

2、简单分析

首先,我们分析一下@ResponseBody是怎样将一个普通的对象转换成Json对象返回。

@responseBody注解的作用是将controller的方法返回的对象通过适当的转换器(默认使用MappingJackson2HttpMessageConverte(Spring 4.x以下使用的是MappingJackson2HttpMessageConverte))转换为指定的格式之后,写入到response对象的body区,需要注意的是,在使用此注解之后不会再走试图处理器,而是直接将数据写入到输入流中,他的效果等同于通过response对象输出指定格式的数据。

作用等同于response.getWriter.write(JSONObject.fromObject(user).toString());

3、怎么处理

总的来说主要有两种处理方式

如何避免精度丢失呢?最常用的办法就是待转化的字段统一转成String类型

那么怎样转化呢?

一般有两种方式:

首先我们要在maven中添加必须的依赖

  <dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.8.6</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.6</version>
</dependency>

方式一.

1、在待转化的字段之上加上@JsonSerialize(using=ToStringSerializer.class)注解,如图所示:

@JsonInclude(JsonInclude.Include.NON_NULL)
public class ProductVo { @JsonSerialize(using=ToStringSerializer.class)
private Long productId private String productName;
get,set省略

Controller方法不需要特殊处理,但是使用这种时,如果需要转换的字段较多,就显得比较繁琐。

让我们看看效果

方法二.

所以,我们可以采用配置spring的消息转换器的ObjectMapper为自定义的类

public class CustomObjectMapper extends ObjectMapper {

    public CustomObjectMapper() {
super();
SimpleModule simpleModule = new SimpleModule();
simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
registerModule(simpleModule);
}
}

然后,我们还需要在SpringMVC的配置文件中加上如下配置

<mvc:annotation-driven >
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<constructor-arg index="0" value="utf-8" />
<property name="supportedMediaTypes">
<list>
<value>application/json;charset=UTF-8</value>
<value>text/plain;charset=UTF-8</value>
</list>
</property>
</bean>
<-对日期进行转化的->
<bean
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean class="com.jay.jackson.util.CustomObjectMapper">
<property name="dateFormat">
<bean class="java.text.SimpleDateFormat">
<constructor-arg type="java.lang.String" value="yyyy-MM-dd HH:mm:ss" />
</bean>
</property>
</bean>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>

至此就大功告成了,Controller方法不需要特殊处理,代码如下:

/**
* 跳转到首页
* @param request
* @param response
*/
@RequestMapping(value="/index", method = RequestMethod.GET)
public String page(HttpServletRequest request, HttpServletResponse response){
return "/index";
} @RequestMapping(value = "/getProducts",method = RequestMethod.POST)
@ResponseBody
public List getProducts(HttpServletRequest request,HttpServletResponse response){
List<ProductVo> productVos=new ArrayList<>();
for (int i=1;i<=2;i++){
ProductVo productVo= new ProductVo();
productVo.setProductId(20170720125047233L+i);
productVo.setProductName("测试商品"+i);
productVos.add(productVo);
}
return productVos;
} @RequestMapping(value = "/getUsers",method = RequestMethod.POST)
@ResponseBody
public List<UserVo> getUsers(){
List<UserVo> userVos=new ArrayList<>();
for (int i=1;i<=2;i++){
UserVo userVo=new UserVo();
userVo.setUserid((long)i);
userVo.setUserName("测试用户"+i);
userVo.setCreateTime(new Date());
userVos.add(userVo);
}
return userVos;
}

我们来看效果。

相关代码:https://github.com/XWxiaowei/JavaWeb.git

Spring MVC自定义消息转换器(可解决Long类型数据传入前端精度丢失的问题)的更多相关文章

  1. 后端传给前端Long类型数据,导致精度丢失

    1.前几天遇到了一个问题,后端向前端传递一个Long类型的数据,前端拿到的值不对. 2.当Long类型的数据大于17位时候,就会出现精度丢失的情况. 3.解决办法 我们采用的解决方案是将后端的Long ...

  2. 后端Long类型传到前端精度丢失的正确解决方式

    原因:前端js对Long类型支持的精度不够,导致后端使用的Long传到前端丢失精度,比如现在分布式id生成算法"雪花算法"在使用中就会出现问题. 解决方式: 1.后端的Long类型 ...

  3. 两个Double类型相减出现精度丢失问题

    两个Double类型相减出现精度丢失问题 720.50-279.5=440.099999999 而不是440.1 解决方法,将数据库中的类型改为decimal类型,小数精确到2位

  4. Spring MVC配置CORS(解决跨域请求)

    1. CORS 简介 同源策略(same origin policy)是浏览器安全的基石.在同源策略的限制下,非同源的网站之间不能发送 ajax 请求的. 为了解决这个问题,w3c 提出了跨源资源共享 ...

  5. Spring MVC RedirectAttributes的用法解决办法

    Spring MVC RedirectAttributes的用法很久没发过技术贴了,今天对于一个问题纠结了2小时,遂放弃研究用另一种方法解决,奈何心中一直存在纠结,发帖求解 我先解释下什么是Redir ...

  6. Spring MVC 自动为对象注入枚举类型

    原文地址:http://1358440610-qq-com.iteye.com/blog/2079048 如果一个对象里面有枚举类型的话,则Spring MVC是不能够直接进行注入的,因为它只实现了一 ...

  7. spring mvc 文件下载 get请求解决中文乱码问题

    方案简写,自己或有些基础的可以看懂,因为没时间写的那么详细 方案1 spring mvc解决get请求中文乱码问题, 在tamcat中server.xml文件 URIEncoding="UT ...

  8. Spring MVC全局异常后返回JSON异常数据

    问题: 当前项目是作为手机APP后台支持,使用spring mvc + mybaits + shiro进行开发.后台服务与手机端交互是发送JSON数据.如果后台发生异常,会直接返回异常页面,显示异常内 ...

  9. Spring MVC 使用介绍(十五)数据验证 (二)依赖注入与方法级别验证

    一.概述 JSR-349 (Bean Validation 1.1)对数据验证进一步进行的规范,主要内容如下: 1.依赖注入验证 2.方法级别验证 二.依赖注入验证 spring提供BeanValid ...

随机推荐

  1. 【转】UINavigationController 直接返回到第一级目录

    原文网址:http://blog.csdn.net/justinjing0612/article/details/7360852 [self.navigationController popViewC ...

  2. MySQL:常用语句

    ylbtech-MySQL:常用语句 1.返回顶部 1. -- ---------------------------- -- Table structure for st_student -- -- ...

  3. linux更换阿里云的源的shell脚本

    #!/bin/bash##########################################Function: update source#Usage: bash update_sour ...

  4. jquery的ajax同步异步执行

    大家先看一段简单的jquery ajax 返回值的js 代码 function getReturnAjax{  $.ajax({    type:"POST",    http:/ ...

  5. [LnOI2019]长脖子鹿省选模拟赛 东京夏日相会

    这里来一发需要开毒瘤优化,并且几率很小一遍过的模拟退火题解... 友情提醒:如果你很久很久没有过某一个点,您可以加上特判 可以像 P1337 [JSOI2004]平衡点 / 吊打XXX 那道题目一样 ...

  6. 题解 UVA10587 【Mayor's posters】

    先讲一下:dalao @lisuier 发布的前一篇题解严格来讲是有错误的 比如下一组数据: 1 3 1 10 1 4 7 10 显然答案是3,然而用lisuier dalao的程序做出来的答案是2( ...

  7. Spark2.0.2+Zeppelin0.6.2 环境搭建 初探

    0.抱怨与其他(此部分与标题没有太多联系): 首先一点想说的是版本问题,为什么标题我会写清楚版本号呢!原因就是版本不对真的很会坑人. 就在写这篇博客的同一天,我还写了另一篇,是 Hadoop2.7.3 ...

  8. 讲究地使用 List

    本篇旨意在于讨论List的基本用法,不做全面讲解,仅仅涉及构造函数List.Add.RemoveAt 先看看这几个函数的代码 1.构造函数 static readonly T[] _emptyArra ...

  9. python练习--1、简易登录接口

    function:用于实现简单的用户登录接口. description:用户信息存储于字典中,增加用户需手动写入代码中.最多可以尝试登录9次,首次使用会先在程序目录下创建锁文件.若在用户栏输入quit ...

  10. VMWare虚拟机Centos 6.9中的 linux 配置静态ip地址上外网

    1.查看网络 # ifconfig 发现网络还没有配置,ping不通 2.修改网卡配置文件 # vim /etc/sysconfig/network-scripts/ifcfg-eth0 添加如下配置 ...