当前位置: 首页 > 知识库问答 >
问题:

如何防止Gson将长数字(json字符串)转换为科学记数法格式?

翟俊名
2023-03-14

我需要将json字符串转换为java对象,并将其显示为long。json字符串是一个固定的长数字数组:

{numbers
[ 268627104, 485677888, 506884800 ] }

要转换的代码在所有情况下都可以正常工作,但以0结尾的数字除外。它将这些转换为科学符号数字格式:

   public static Object fromJson(HttpResponse response, Class<?> classOf)
    throws IOException {
    InputStream instream = response.getResponseInputStream();                   

    Object obj = null;
    try {
        Reader reader = new InputStreamReader(instream, HTTP.UTF_8);

        Gson gson = new Gson();

        obj = gson.fromJson(reader, classOf); 

        Logger.d(TAG, "json --> "+gson.toJson(obj));
    } catch (UnsupportedEncodingException e) {
        Logger.e(TAG, "unsupported encoding", e);
    } catch (Exception e) {
        Logger.e(TAG, "json parsing error", e);
    }

    return obj;
}

实际结果:Java对象:268627104、485677888、5.068848E 8

请注意,最后一个数字已转换为科学记数法格式。有人能建议如何解决它、防止它或撤销它吗?我正在使用Gson v1.7.1

共有3个答案

姜嘉赐
2023-03-14

我有一个类似的问题,它不仅将整数转换为double,而且对于某些长的数字,它实际上会失去精度,如相关问题中所述。

我跟踪了这个转换到ObjectTypeAdapter的read方法,具体是:

case NUMBER:
  return in.nextDouble();

可能可以为Object插入修改后的TypeAdapter,但我无法让它工作,所以我只是将read方法(Object read(JsonReader in))复制到我自己的代码并将上述行修改为:

case NUMBER:
    final String s = in.nextString();
    try {
        return Integer.parseInt(s);
    } catch (NumberFormatException e) {
        // ignore
    }
    try {
        return Long.parseLong(s);
    } catch (NumberFormatException e) {
        // ignore
    }
    return Double.parseDouble(s);

我希望Gson默认这样做...

然后我把其他连接部分放在一个助手方法中,看起来像这样:

public static Object parse(final Reader r) {
    try (final JsonReader jr = new JsonReader(r)) {
        jr.setLenient(true);
        boolean empty = true;
        Object o = null;
        try {
            jr.peek();
            empty = false;
            o = read(jr);
        } catch (EOFException e) {
            if (!empty) {
                throw new JsonSyntaxException(e);
            }
        }
        if (o != null && jr.peek() != JsonToken.END_DOCUMENT) {
            throw new JsonIOException("JSON document was not fully consumed.");
        }
        return o;
    } catch (IOException e) {
        throw new JsonIOException(e);
    }
}

因此,现在不再使用新的Gson()。从JSON(r,Object.class),我调用解析(r)。

这对我很有效,因为我希望能够解析具有任何结构的json数据,但是如果您有一个特定的目标类,您可能只需要消除该类成员中出现的Object

萧秋月
2023-03-14

另一个解决方法是改用JsonParser类。这将返回Gson对象表示(JsonElement),而不是用户定义的类,但避免了转换为科学符号的问题。

import java.lang.reflect.Type;
import java.util.Map;

import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.google.gson.reflect.TypeToken;

public class GsonTest
{
    public static void main(String[] args)
    {
        String json = "{numbers:[268627104,485677888,506884800]}";

        Gson gson = new Gson();
        Type type = new TypeToken<Map<String, Object>>(){}.getType();
        Map<String, Object> jsonMap = gson.fromJson(json, type);
        System.out.println("Gson output:");
        System.out.println(jsonMap);

        JsonParser jsonParser = new JsonParser();
        JsonElement jsonElement = jsonParser.parse(json);
        System.out.println("JsonParser output:");
        System.out.println(jsonElement);
    }
}

代码输出:

Gson output:  
{numbers=[2.68627104E8, 4.85677888E8, 5.068848E8]}  
JsonParser output:  
{"numbers":[268627104,485677888,506884800]}
林彬
2023-03-14

如果您可以选择序列化为字符串,则可以通过以下方式配置GSON:

GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.setLongSerializationPolicy( LongSerializationPolicy.STRING );
Gson gson = gsonBuilder.create();

这将产生如下结果:

{numbers : [ "268627104", "485677888", "506884800" ] }
 类似资料:
  • 问题内容: 我想将BigInteger数转换为小的科学计数法,例如1.86e + 6,然后再次将该科学计数法转换为Java中的BigInteger数。请帮忙。 问题答案: 最简单的方法是使用a 解析或输出科学计数法字符串。 您可以执行以下操作: 并反向: 更新资料 如果需要更多用户定义的输出,则可以使用。不要忘记设置喜欢的东西,所以你不会得到,说逗号作为小数点分隔符(这是我第一次了,在德语区域)。

  • 我正在尝试从json转换为Java对象。我收到一个json字符串,其中包括一个书籍列表: 我创建了一个名为Books的对象: 另外,我正在使用doGet方法从RESTful webservice中以以下方式检索这些数据: 干杯

  • 我使用python从API中提取数据,并将其存储在数据帧中。我以CSV格式导出数据框,当我使用excel打开它时,一些列(有非常大的数字)会转换为科学符号,我不希望这样。我希望数字保持整数格式。 我尝试在to_csv命令中使用浮点格式选项,但也没有帮助。 这是我的导出命令: 注意:数字在数据框中以整数格式显示。此外,当使用记事本打开csv文件时,数据将以正确的格式显示。 电流输出: 期望输出:

  • 问题内容: 我具有来自Web服务的以下JSON字符串,并且正在尝试将其转换为 我在线上对此进行了验证,这似乎是正确的。现在我在android开发中使用以下代码来利用 这会引发异常和类型不匹配的异常。 问题答案: 在这里,您将获得JSONObject,因此请更改以下行: 具有以下内容: 之后

  • 问题内容: 我在JS中有一个JSON对象,我想将其转换为字符串。这是功能吗? 提前致谢, 问题答案: JSON.stringify() 将值转换为JSON,如果指定了replacer函数,则可以选择替换值,如果指定了replacer数组,则可以选择仅包括指定的属性。

  • 我试图找到一种方法来将像“t2hr8var4tnuloglmibpabyvdri1y02rbx”这样的长字符串ID转换为数字ID。 A=10,B=20,C=50, ABC=10+20+50=80 BAC=20+10+50=80 所以ABC=102050 这个方法不起作用,因为有一个20个字母的字符串会导致一个巨大的数字,所以我如何解决这个问题?提前谢谢你。