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中添加必须的依赖

  1. <dependency>
  2. <groupId>com.fasterxml.jackson.core</groupId>
  3. <artifactId>jackson-annotations</artifactId>
  4. <version>2.8.6</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>com.fasterxml.jackson.core</groupId>
  8. <artifactId>jackson-databind</artifactId>
  9. <version>2.8.6</version>
  10. </dependency>

方式一.

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

  1. @JsonInclude(JsonInclude.Include.NON_NULL)
  2. public class ProductVo {
  3.  
  4. @JsonSerialize(using=ToStringSerializer.class)
  5. private Long productId
  6.  
  7. private String productName;
    get,set省略

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

让我们看看效果

方法二.

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

  1. public class CustomObjectMapper extends ObjectMapper {
  2.  
  3. public CustomObjectMapper() {
  4. super();
  5. SimpleModule simpleModule = new SimpleModule();
  6. simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
  7. simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
  8. registerModule(simpleModule);
  9. }
  10. }

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

  1. <mvc:annotation-driven >
  2. <mvc:message-converters>
  3. <bean class="org.springframework.http.converter.StringHttpMessageConverter">
  4. <constructor-arg index="0" value="utf-8" />
  5. <property name="supportedMediaTypes">
  6. <list>
  7. <value>application/json;charset=UTF-8</value>
  8. <value>text/plain;charset=UTF-8</value>
  9. </list>
  10. </property>
  11. </bean>
    <-对日期进行转化的->
  12. <bean
  13. class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
  14. <property name="objectMapper">
  15. <bean class="com.jay.jackson.util.CustomObjectMapper">
  16. <property name="dateFormat">
  17. <bean class="java.text.SimpleDateFormat">
  18. <constructor-arg type="java.lang.String" value="yyyy-MM-dd HH:mm:ss" />
  19. </bean>
  20. </property>
  21. </bean>
  22. </property>
  23. </bean>
  24. </mvc:message-converters>
  25. </mvc:annotation-driven>

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

  1. /**
  2. * 跳转到首页
  3. * @param request
  4. * @param response
  5. */
  6. @RequestMapping(value="/index", method = RequestMethod.GET)
  7. public String page(HttpServletRequest request, HttpServletResponse response){
  8. return "/index";
  9. }
  10.  
  11. @RequestMapping(value = "/getProducts",method = RequestMethod.POST)
  12. @ResponseBody
  13. public List getProducts(HttpServletRequest request,HttpServletResponse response){
  14. List<ProductVo> productVos=new ArrayList<>();
  15. for (int i=1;i<=2;i++){
  16. ProductVo productVo= new ProductVo();
  17. productVo.setProductId(20170720125047233L+i);
  18. productVo.setProductName("测试商品"+i);
  19. productVos.add(productVo);
  20. }
  21. return productVos;
  22. }
  23.  
  24. @RequestMapping(value = "/getUsers",method = RequestMethod.POST)
  25. @ResponseBody
  26. public List<UserVo> getUsers(){
  27. List<UserVo> userVos=new ArrayList<>();
  28. for (int i=1;i<=2;i++){
  29. UserVo userVo=new UserVo();
  30. userVo.setUserid((long)i);
  31. userVo.setUserName("测试用户"+i);
  32. userVo.setCreateTime(new Date());
  33. userVos.add(userVo);
  34. }
  35. return userVos;
  36. }

我们来看效果。

相关代码: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. 【最短路算法】Dijkstra知识点&代码

    代码: #include<iostream> #include<vector> #include<cstdio> #include<queue> #in ...

  2. ubuntu使用ssh连接远程电脑的方法

    目前,大多数linux distributions都预先安装了ssh的客户端,即可以连接别人的电脑.但也有例外的情况,所以,下面先把ssh的客户端与服务端的安装一并讲了吧. ssh客户端及服务端的安装 ...

  3. P1043 数字游戏

    P1043 数字游戏 题目描述 丁丁最近沉迷于一个数字游戏之中.这个游戏看似简单,但丁丁在研究了许多天之后却发觉原来在简单的规则下想要赢得这个游戏并不那么容易.游戏是这样的,在你面前有一圈整数(一共n ...

  4. hdoj--3790--最短路径问题(双权值迪杰斯特拉)

     最短路径问题 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  5. Coursera Algorithms week2 基础排序 练习测验: Intersection of two sets

    题目原文: Given two arrays a[] and b[], each containing n distinct 2D points in the plane, design a subq ...

  6. HTTP权威协议笔记-9.Web机器人

    经过整个春节的放肆,终于回归了,说实话,春节真心比上班累. 9.1 爬虫及爬行方式 (1) 爬虫:Web爬虫是一种机器人,他们会递归性的对各种信息Web站点进行遍历. (2) 爬行方式:Web机器人会 ...

  7. [转]逐步解說:在 WPF 應用程式中使用 ReportViewer 显示 rdlc

    本文转自:http://msdn.microsoft.com/zh-tw/library/hh273267 若要在 WPF 應用程式中使用 ReportViewer 控制項,您需要將 ReportVi ...

  8. HTML+CSS(10)

    n  组合选择器 多元素选择器 n  描述:给多个元素加同一个样式,多个选择器之间用逗号隔开. n  举例:h1,p,div,body{color:red;} 后代元素选择器(最常用) n  描述:给 ...

  9. Hadoop学习笔记(一)Hadoop的单节点安装

    要想深入学习Hadoop分布式文件系统,首先需要搭建Hadoop的实验环境,Hadoop有两种安装模式,即单节点集群模式安装(也称为伪分布式)和完全分布式模式安装,本节只介绍单节点模式的安装,参考官方 ...

  10. CentOS 7 中配置通过 daemon 模式启动的 Tomcat 8 服务

    距离上次折腾已经有很长一段时间了... 不说这个,刚好有空闲,把这两天折腾的 Tomcat 8 的服务配置整理出来收录一下. 1.JDK安装 1)检查服务器是否预装了 openJdk,如果有就删除,在 ...