1、背景
已运行的大型项目中,字符串转Map使用Gson工具类进行转换,不敢贸然使用其它工具类(如FastJson),这是前提。
如果你是学习或者小型项目,Gson使用出现浮点转换科学记数法的问题,可以换成FastJson 工具或者其它工具,就能解决此问题。
2、问题描述
String jsonStr="{\"data\":0.000001}";
Map<String,Object> jsonMap= JsonUtil.jsonStrToMap(jsonStr);
System.out.println(JsonUtil.toJson(jsonMap));
运行结果
{nc: 1.0E-6}
3、解决思路
Java Map 对象存放数据时,会自动将浮点类型变成科学记数法。
Map map =new HashMap();
map.put("a",0.000001);
System.out.println(JsonUtil.toJson(map));
运行结果
{a: 1.0E-6}
Map 对象存放 BigDecimal 数据时,会保持原数据。
Map map =new HashMap();
map.put("a",0.000001);
map.put("b",new BigDecimal("0.000002"));
System.out.println(JsonUtil.toJson(map));
运行结果:
{a: 1.0E-6, b: 0.000002}
使用Gson进行Json字符串与Java Map对象间转换时,Json字符串里 如果是numberic(double、long、int),Gson会在转成java对象时将该属性默认认为是Double类型,就会出现变成科学记数法的问题。
解决方法是进行数据进行保装。
4、解决方法
1、gson反序列化适配器
import com.google.gson.*;import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;/*** 用于解决当Json字符串中含用浮点类型(如0.0000004)值,在反序列化转换成Map时,会变成科学记数法的问题*/
public class GsonDoubleAdapter implements JsonDeserializer<HashMap<String, Object>> {@Overridepublic HashMap<String, Object> deserialize(JsonElement json,Type typeOfT, JsonDeserializationContext context)throws JsonParseException {HashMap<String, Object> dataMap = new HashMap<>();JsonObject jsonObject = json.getAsJsonObject();Set<Map.Entry<String, JsonElement>> entrySet = jsonObject.entrySet();for (Map.Entry<String, JsonElement> entry : entrySet) {Object ot = entry.getValue();if(ot instanceof JsonPrimitive){dataMap.put(entry.getKey(), ((JsonPrimitive) ot).getAsString());}else{dataMap.put(entry.getKey(), ot);}}return dataMap;}
}
2、在创建 gson对象时,添加适配置器:
static Type typeToken = new TypeToken<HashMap<String, Object>>(){}.getType();
static Gson gson= new GsonBuilder().serializeNulls()//.registerTypeAdapter(typeToken,new GsonDoubleAdapter())//此行为新增加的适配器.disableHtmlEscaping()//.create();
3、json字符串转Map对象的方法也要修改,如下:
public static Map<String, Object> jsonStrToMap(String jsonStr) {try{return gson.fromJson(jsonStr, typeToken); // 此处变成 typeToken}catch (Exception e){e.printStackTrace();}return null;
}
5、验证
String jsonStr="{\"nc\":0.000001}";
Map<String,Object> jsonMap= JsonUtil.jsonStrToMap(jsonStr);
System.out.println(JsonUtil.toJson(jsonMap));
运行结果:
{nc: 0.000001}