2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > gson 解析int类型转换为double解决方案

gson 解析int类型转换为double解决方案

时间:2020-06-28 14:05:09

相关推荐

gson 解析int类型转换为double解决方案

背景:

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.ponent;import java.io.IOException;import java.util.*;@Componentpublic 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();

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。