问题你提描述
今天再使用Gson处理json数据的时候碰到了一个问题 , 当我使用如下代码解析json数据的时候 , requestTime就变为了double类型
Map<String , Object> sourceValueMap = gson.fromJson(jsonData , new TypeToken<HashMap<String , Object>>(){}.getType());
蓝色框为原始数据 , 红色框为解析之后的数据
解决办法 :
再翻阅了众多资料之后 , 发现有两种解决办法
1.修改源码
2.添加指定类型的自定义解密工具
相对来说第二种解决办法显然更轻松
在上面的代码中,你可以测试网络中找到的其他解决方式,你会发现所有设置都失效了。
原因是,当你使用 Class 对象作为解析类型时,Gson 会转入你自定义的解析器,而使用 TypeToken 时,Gson 无法将传入的参数与绑定的 TypeToken 对应,最终使用默认解析器。
实现过程
创建自定义的 ObjectTypeAdapter 对象,并实现其工厂方法
public final class MapTypeAdapter 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 MapTypeAdapter(gson); } return null; } }; private final Gson gson; private MapTypeAdapter(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<>(); in.beginArray(); while (in.hasNext()) { list.add(read(in)); } in.endArray(); return list; case BEGIN_OBJECT: Map<String, Object> map = new LinkedTreeMap<>(); in.beginObject(); while (in.hasNext()) { map.put(in.nextName(), read(in)); } in.endObject(); return map; case STRING: return in.nextString(); case 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(); } } @Override public void write(JsonWriter out, Object value) throws IOException { if (value == null) { out.nullValue(); return; } //noinspection unchecked TypeAdapter<Object> typeAdapter = (TypeAdapter<Object>) gson.getAdapter(value.getClass()); if (typeAdapter instanceof ObjectTypeAdapter) { out.beginObject(); out.endObject(); return; } typeAdapter.write(out, value); } }
使用自定义工厂方法取代 Gson 实例中的工厂方法。
public class GsonFactory { 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, MapTypeAdapter.FACTORY); break; } } } catch (Exception e) { e.printStackTrace(); } return gson; } }
使用
这样的话问题完美解决 , 数据也一切正常