Java gson反序列化时,Json字符串中含有浮点类型(0.000001)时,在反序列化转换成Map时,会变成科学记数法

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>> {

    @Override
    public 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}

你可能感兴趣的:(#,Java高级,java,json,gson,浮点类型,科学记数法)