我有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行)中,offset
为0
,但转换后为0.0
。截图:
为什么会这样?如何解决这个问题?
答案 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导航和建议方面具有更强大的功能。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没有足够的类型信息并且工作得非常好。