Gson - 一个场的两个json键
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Gson - 一个场的两个json键相关的知识,希望对你有一定的参考价值。
我读过Gson文档并决定使用它。但我无法弄清楚如何为一个字段提供两个不同的JSON密钥。例如,我有:
public class Box {
@SerializedName("w")
private int width;
@SerializedName("h")
private int height;
@SerializedName("d")
private int depth;
}
对于字段width
,我想用密钥w
或替代密钥width
反序列化它,如果在JSON字符串中找不到第一个。
例如,{"width":3, "h":4, "d":2}
或{"w":3, "h":4, "d":2}
应该可以解析为Box类。
我怎样才能使用注释或者使用TypedAdapter
?
答案
一个解决方案可能是写这样的TypeAdapter
:
package stackoverflow.questions.q19332412;
import java.io.IOException;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.*;
public class BoxAdapter extends TypeAdapter<Box>
{
@Override
public void write(JsonWriter out, Box box) throws IOException {
out.beginObject();
out.name("w");
out.value(box.width);
out.name("d");
out.value(box.depth);
out.name("h");
out.value(box.height);
out.endObject();
}
@Override
public Box read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
in.beginObject();
Box box = new Box();
while (in.peek() == JsonToken.NAME){
String str = in.nextName();
fillField(in, box, str);
}
in.endObject();
return box;
}
private void fillField(JsonReader in, Box box, String str)
throws IOException {
switch(str){
case "w":
case "width":
box.width = in.nextInt();
break;
case "h":
case "height":
box.height = in.nextInt();
break;
case "d":
case "depth":
box.depth = in.nextInt();
break;
}
}
}
注意把Box
和BoxAdapter
放在同一个包装里。我将Box
字段的可见性更改为打包可见以避免使用getter / setter。但如果你愿意,你可以使用getter / setter。
这是调用代码:
package stackoverflow.questions.q19332412;
import com.google.gson.*;
public class Q19332412 {
/**
* @param args
*/
public static void main(String[] args) {
String j1 = "{\"width\":4, \"height\":5, \"depth\"=1}";
String j2 = "{\"w\":4, \"h\":5, \"d\"=1}";
GsonBuilder gb = new GsonBuilder().registerTypeAdapter(Box.class, new BoxAdapter());
Gson g = gb.create();
System.out.println(g.fromJson(j1, Box.class));
System.out.println(g.fromJson(j2, Box.class));
}
}
这就是结果:
框[宽度= 4,高度= 5,深度= 1]
框[宽度= 4,高度= 5,深度= 1]
另一答案
更新:
在@SerializedName
注释中可以实现同样的alternate
名称。
class Box {
@SerializedName("w", alternate = ["width"])
private val width: Int = 0
@SerializedName("h", alternate = ["height"])
private val height: Int = 0
@SerializedName("d")
private val depth: Int = 0
}
以上是关于Gson - 一个场的两个json键的主要内容,如果未能解决你的问题,请参考以下文章