背景:
Gson在使用gson.fromJson对json对象中带int类型的数据转换时候,会存在nt类型转换为double的情况,原因是Gson在解释数据过程中的number类型处理导致的;具体见ObjectTypeAdapter类 的read方法

@Override public Object read(JsonReader in) throws IOException {JsonToken token = in.peek();switch (token) {case BEGIN_ARRAY:List<Object> list = new ArrayList<Object>();in.beginArray();while (in.hasNext()) {list.add(read(in));}in.endArray();return list;case BEGIN_OBJECT:Map<String, Object> map = new LinkedTreeMap<String, Object>();in.beginObject();while (in.hasNext()) {map.put(in.nextName(), read(in));}in.endObject();return map;case STRING:return in.nextString();// 处理number类型数据,会自动转换为double类型case NUMBER:return in.nextDouble();case BOOLEAN:return in.nextBoolean();case NULL:in.nextNull();return null;default:throw new IllegalStateException();}}

代码中使用到的Gson版本为2.8.6版本,笔者本人也尝试过使用Gson的高版本2.9.1版本,Number类型的实现方式稍有出入,不过结果还是相同解析int类型数据依旧转换为double

<dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId><version>2.6.4</version></dependency>

示例:

 public static void main(String[] args) {String str = "{\"msg\":\"操作成功\",\"code\":200,\"data\":\"$f8ff483ee9d57d5ef5d1adf4385a24b\"}";BaseResult baseResult = new Gson().fromJson(str,BaseResult.class);System.out.println(111);}

解决方案:自定义TypeAdapter,复制ObjectTypeAdapter中的所有代码,只修改read方法中关于Number类型的处理

package com.yojofly.server.config;import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.internal.LinkedTreeMap;
import com.google.gson.internal.bind.ObjectTypeAdapter;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import org.springframework.stereotype.Component;import java.io.IOException;
import java.util.*;@Component
public class GsonTypeAdaptor extends TypeAdapter<Object> {public static final TypeAdapterFactory FACTORY = new TypeAdapterFactory() {@SuppressWarnings("unchecked")@Override public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {if (type.getRawType() == Object.class) {return (TypeAdapter<T>) new GsonTypeAdaptor(gson);}return null;}};private  Gson gson;GsonTypeAdaptor(Gson gson) {this.gson = gson;}@Override public Object read(JsonReader in) throws IOException {JsonToken token = in.peek();switch (token) {case BEGIN_ARRAY:List<Object> list = new ArrayList<Object>();in.beginArray();while (in.hasNext()) {list.add(read(in));}in.endArray();return list;case BEGIN_OBJECT:Map<String, Object> map = new LinkedTreeMap<String, Object>();in.beginObject();while (in.hasNext()) {map.put(in.nextName(), read(in));}in.endObject();return map;case STRING:return in.nextString();case NUMBER:// 自定义的number类型处理String s = in.nextString();if (s.contains(".")) {return Double.valueOf(s);} else {try {return Integer.valueOf(s);} catch (Exception e) {return Long.valueOf(s);}}case BOOLEAN:return in.nextBoolean();case NULL:in.nextNull();return null;default:throw new IllegalStateException();}}@SuppressWarnings("unchecked")@Override public void write(JsonWriter out, Object value) throws IOException {if (value == null) {out.nullValue();return;}TypeAdapter<Object> typeAdapter = (TypeAdapter<Object>) gson.getAdapter(value.getClass());if (typeAdapter instanceof ObjectTypeAdapter) {out.beginObject();out.endObject();return;}typeAdapter.write(out, value);}
}

最后需要将自定义的GsonTypeAdaptor注册到GsonBuilder中

public static final Gson gson = getGson();public static Gson getGson() {Gson gson = new GsonBuilder().create();try {Field factories = Gson.class.getDeclaredField("factories");factories.setAccessible(true);Object o = factories.get(gson);Class<?>[] declaredClasses = Collections.class.getDeclaredClasses();for (Class c : declaredClasses) {if ("java.util.Collections$UnmodifiableList".equals(c.getName())) {Field listField = c.getDeclaredField("list");listField.setAccessible(true);List<TypeAdapterFactory> list = (List<TypeAdapterFactory>) listField.get(o);int i = list.indexOf(ObjectTypeAdapter.FACTORY);list.set(i, GsonTypeAdaptor.FACTORY);break;}}} catch (Exception e) {e.printStackTrace();}return gson;}

示例:

 public static void main(String[] args) {String str = "{\"msg\":\"操作成功\",\"code\":200,\"data\":\"$f8ff483ee9d57d5ef5d1adf4385a24b\"}";BaseResult baseResult = gson.fromJson(str,BaseResult.class);System.out.println(111);}


最后解决该问题。
网上也有通过如下代码实现自定义typeAdapter注册,但笔者多次尝试如下代码并不生效

new GsonBuilder().registerTypeAdapter(new TypeToken<Map<String,Object>>(){}.getType(),new DataTypeAdapter()).create();

gson 解析int类型转换为double解决方案相关推荐

  1. java中int转换double类型_Java 程序将int类型变量转换为double

    Java 程序将int类型变量转换为double 在此程序中,我们将学习如何在Java中将整数(int)变量转换为double值. 要理解此示例,您应该了解以下Java编程主题: 示例1:使用类型转换 ...

  2. to_string()函数----将int类型转换为string型

    需要的头文件: #include<iostream> 需要的其他东西: using namespace std; 函数的作用: 将一个int类型转换为string型 用法: int sum ...

  3. c语言 int类型转换为string类型

    1. int类型 12345 转换为char类型 12345: #include "stdio.h" /** *int类型转换为string类型 *Int_i: 要转换的int类型 ...

  4. Java中如何将int 类型转换为 Long类型

    Long l = (Long)3; 1 很多同学可能会用上面的方法将int类型转换为Long类型,但事实上这样是不可行的.因为Long是包装类,而int是值类型数据,两者是不能这样强转的. long ...

  5. c语言的int类型转换为(void *)类型

    直接看代码 将int型转为void *类型后,再将void *类型转为int类型,gcc编译的时候会报警告如下 结果还是能运行成功的 (void *)i=0xf&i=0x7fff14e4de7 ...

  6. int类型转为double

    虽然小范围的类型转大范围的类型能够隐式转换,但当有表达式操作时需要强制转换,否者可能失去精度 . 左到右范围从小到大:byte->short->int->long->float ...

  7. 回复 C++中如何将Int类型转换为String类型?

    像是C#,java等高级语言中,int转String类型都是很简单的,但是C++中好像很麻烦,我查了百度的资料,我找到了转换的方式: 我想问的是,为什么要这么做,而不提供直接转换的方式? int 转换 ...

  8. int类型转换为string类型

    int i=1;    String str=""; 第一种方法:s = i+""; 第二种方法:str = String.valueOf(i); 更多好内容戳 ...

  9. java int 16进制字符串_关于将java int类型转换为16进制字符串的问题

    package p5.com.byd.mes.dev.tool.baseToChar; /** * 任意进制转换器 * @author solar */ public class Decimal { ...

最新文章

  1. Linux执行df -h等操作卡住问题
  2. placeholder 颜色更改
  3. 0.1 hint crack
  4. 暴雪还不赶快?劳拉与光之守护者PC平台登陆
  5. [能力提升][费曼学习法]学习方法
  6. java cpu高_Java中的CPU占用高和内存占用高的问题排查
  7. 关于字节面试过程不会的算法题总结
  8. php分布式缓存系统 Memcached 入门
  9. Jquery+asp.net实现Ajax方式文件下载实例代码
  10. 外汇EA 指标加密方法
  11. K3 WISE修改单据表头字段默认值
  12. C#全局钩子参考文章
  13. oracle中字符串长度计算,根据 oracle 标准计算超长字符串的长度
  14. 接近开关NPN和PNP区别
  15. 4.1 制定项目章程
  16. 【泛函分析】 1 距离空间
  17. 【第一组】第三次冲刺例会
  18. fastadmin 自定义按钮 btn-ajax 执行成功后 自动刷新
  19. 小程序坑录-wx.getLocation接口申请
  20. 利用python批量将excel中文翻译成英文

热门文章

  1. 怎样提高电脑开机速度
  2. python can总线_MicroPython教程之TPYBoard v102 CAN总线通信
  3. 真正的程序员到底应该是什么样子的?
  4. 贝叶斯法则与先验后验概率以及似然度的关系
  5. Hans Petter Langtangen
  6. Java设计模式总结——6大设计原则
  7. wangEditor 5 - 修改工具栏 toolbar 默认背景色(去掉背景颜色改为透明)
  8. Python渗透测试之Scapy模块情报收集
  9. 搞语音的有关音频的基础知识
  10. 宠物保存服务市场现状及未来发展趋势分析