网上常见方法:
方式1:添加指定类型的自定义解密工具。
第一步,创建自定义的 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 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;
}
注意:上面使用了反射,部分机型可能不兼容,项目中红米手机这种方式报错,所以这种方式放弃了,不过这个方式是有效得
private static Gson buildGson() {
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapterFactory(MapTypeAdapter .FACTORY);
return gsonBuilder.create();
}
上面这种使用是不生效得,网上很多这种文章,实则不生效
方式2: 使用fastjson
String jsonStr = JSONObject.toJSONString(person1);
JSONObject jsonObject = JSONObject.parseObject(jsonStr);
方式3:使用com.google.gson.Gson
//正常
Gson gson = new GsonBuilder().create();
JsonObject jsonObject = gson.fromJson(gson.toJson(person1), JsonObject.class);
//异常,会把整数转成小数
Gson gson = new GsonBuilder().create();
JSONObject jsonObject = gson.fromJson(json, JSONObject.class);
项目中使用得该方式
方式4 使用高版本Gson
/**
* 获取list
*
* @param json 数据源
* @param type TypeToken.getParameterized(List.class, xxx.class).getType();
*/
public static List<?> fromJson(String json, Type type) {
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.setObjectToNumberStrategy(ToNumberPolicy.LAZILY_PARSED_NUMBER);
Gson gson = gsonBuilder.create();
return gson.fromJson(json, type);
}