1 Gson
1.1 Gson介绍:
- GSON是Google提供的用来在Java对象和JSON数据之间进行映射的Java类库。可以将一个Json字符转成一个Java对象,或者将一个Java转化为Json字符串。
1.2 遇到的问题:本人在工作时遇到过这类问题:将Json转换为Java对象会发现精度丢失的问题,具体案例如下:
public static void transferJsonToMap() {
String json = "{"birthday":"1996-03-18","date":"May 10, 2019 3:32:17 PM","name":"joebig7","weight":65.5,"id":1412102169,"age":24,"height":179.2}";
//将Json转换为Map
Map<String, Object> map = JsonUtil.fromJson(json, new TypeToken<Map<String, Object>>() {
}.getType());
System.out.println(map);
}
输出结果如下:
{birthday=1996-03-18, date=May 10, 2019 3:32:17 PM, name=joebig7, weight=65.5, id=1.412102169E9, age=24.0, height=179.2}
可以发现通过Gson进行转换后Map中的int类型变为了Double,然后Long类型变为了科学计数法的。
1.3 解决方法
- 1 重写类型适配器:首先需要明确的是,Gson通过一个类ObjectTypeAdapter来进行类型的转换,主要代码如下:
可以看见,Gson对于数据类型没有做具体的区分,统一转换成了Long类型。可以通过自定义一个类型转换器来解决这个问题,具体d代码如下: 代码重写了对Number类型对的处理逻辑
public final class GeneralTypeAdapter extends TypeAdapter<Object> {
@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:
String var1 = in.nextString();
if (var1.contains(".") || var1.contains("e") || var1.contains("E")) {
return Double.parseDouble(var1);
}
return Long.parseLong(var1);
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 {
}
}
public static <T> T fromJson(String json, Type T) {
GsonBuilder gsonBuilder = new GsonBuilder();
Gson gson = gsonBuilder.registerTypeAdapter(new TypeToken<Map<String, Object>>() {
}.getType(), new GeneralTypeAdapter()).create();
return gson.fromJson(json, T);
}
在实际使用中,最好将json转换到具体的Bean对象就不会存在类型的问题。
2 FastJson
2.1 FastJson介绍: 和Gson类型,Fastjson是一个Java语言编写的JSON处理器。
- 遇到的问题:通过FastJson将json转换成JSONObject或者Map类型的时候,对于浮点类型会被默认转换成BigDecimal类型
2.2 解决方式:
// 1 可以通过全局设置,禁用BigDeccimal的方式来解决这个问题
public static void getJsonObject(String str){
JSON.DEFAULT_PARSER_FEATURE &= ~Feature.UseBigDecimal.getMask();
Map map = JSON.parseObject(str, Map.class);
System.out.println(map.toString());
}
// 2 可以通过局部设置,禁用BigDeccimal
public static void getJsonObject(String str){
int disableDecimalFeature = JSON.DEFAULT_PARSER_FEATURE & ~Feature.UseBigDecimal.getMask();
Map map = JSON.parseObject(str, Map.class,disableDecimalFeature);
System.out.println(map.toString());
}
不过在实际项目中,最好是定义具体的bean来进行转换就不会出现这类问题