解析json字符串时,Gson将int转换为double

时间:2017-01-25 13:37:16

标签: android json gson

我有this个JSON文件到我的资产中。我正在使用Gson将其解析为以下模型类:

public class SearchRequest {

    private ArrayList<String> _source;
    private int from;
    private int size;
    private Object sort;
    private Object query;


    public void setFrom(int from) {
        this.from = from;
    }

    public void setSize(int size) {
        this.size = size;
    }

    public void setArtist(String artistName) {
        Gson gson = new Gson();
        JsonObject object = gson.toJsonTree(query).getAsJsonObject();
        JsonArray should = object.getAsJsonObject("function_score").getAsJsonObject("query")
                .getAsJsonObject("bool").getAsJsonArray("should");
        should.get(0).getAsJsonObject().getAsJsonObject("match").addProperty("album_artist", artistName);
        should.get(1).getAsJsonObject().getAsJsonObject("nested").getAsJsonObject("query")
                .getAsJsonObject("bool").getAsJsonArray("must").get(0).getAsJsonObject()
                .getAsJsonObject("match").addProperty("tracks.artist", artistName);
        query = gson.fromJson(object.toString(), query.getClass());
    }
}

当我将此JSON转换为此类的对象时,query对象变为LinkedTreeMap。但在此转换中,作为整数的键offset变为double。在我的JSON(第50行)中,offset0,但转换后为0.0。截图:

enter image description here

为什么会这样?如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

  

如何解决这个问题?

这不是一个固定的主题,没有什么可担心的。

  

为什么会这样?

您的JSON&lt; - &gt; Java映射不提供除最顶层映射之外的任何映射。由于缺少目标类型信息,这使得Gson的工作方式与此类似,而LinkedTreeMap在内部使用 。像0这样的文字可能看起来像整数,也是JSON格式的合法浮点值:JSON规范仅声明数字,并且不对#34进行任何更正; integerness&#34 ;.由于没有足够的关于反序列化数据类型的信息,Gson应用默认的解析策略,并选择java.lang.Double作为一种类型,可以容纳任何其他标准数值,这些数值可以容纳较少的重要位(long s可以适合double的房间很容易;但不确定Gson对BigDecimal做了什么 - JSON规范似乎没有任何限制)。所以这只是内部Gson表示,你有几个选择:

  • 您可以声明甚至可以避免内部LinkedTreeMap的映射(由专用工具编写或生成)。乏味?也许。但是在类型安全,javac控制或您最喜欢的IDE导航和建议方面具有更强大的功能。
  • Gson提供了一系列方法将JSON树值转换为目标类型:getAsJsonObject()getAsJsonArray()getAsInt(),以及更多允许在表示中获取目标对象的方法想。例如,
final Object value = searchRequest.query
        .get("function_score").getAsJsonObject()
        .get("functions").getAsJsonArray()
        .get(0).getAsJsonObject()
        .get("linear").getAsJsonObject()
        .get("date").getAsJsonObject()
        .get("offset").getAsInt();
System.out.println(value + " " + value.getClass());

给出:

  

0 class java.lang.Integer

因为get("offset").getAsInt()内部为JSON原语实现为return isNumber() ? getAsNumber().intValue() : ...;

  • 您可以应用部分映射。例如,您可以提取date JSON树并将其转换为声明private int offset;字段的特殊映射:gson.fromJson(dateJsonObject, DateMapping.class)

同样,Gson没有足够的类型信息并且工作得非常好。