對於Long 類型的數據,若是咱們在Controller層經過@ResponseBody將返回數據自動轉換成json時,不作任何處理,而直接傳給前端的話,在Long長度大於17位時會出現精度丟失的問題。前端
至於爲啥丟失,咱們在此處不探討。java
如圖所示:後端返回數據以下:git
而前端接收的數據時就丟失了精度github
首先,咱們分析一下@ResponseBody是怎樣將一個普通的對象轉換成Json對象返回。spring
@responseBody註解的做用是將controller的方法返回的對象經過適當的轉換器(默認使用MappingJackson2HttpMessageConverte(Spring 4.x如下使用的是MappingJackson2HttpMessageConverte))轉換爲指定的格式以後,寫入到response對象的body區,須要注意的是,在使用此註解以後不會再走試圖處理器,而是直接將數據寫入到輸入流中,他的效果等同於經過response對象輸出指定格式的數據。json
做用等同於response.getWriter.write(JSONObject.fromObject(user).toString());後端
總的來講主要有兩種處理方式mvc
如何避免精度丟失呢?最經常使用的辦法就是待轉化的字段統一轉成String類型app
那麼怎樣轉化呢?maven
通常有兩種方式:
首先咱們要在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>
方式一.
一、在待轉化的字段之上加上@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