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來進行轉換就不會出現這類問題