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;
        }
    }
}

注意把BoxBoxAdapter放在同一个包装里。我将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键的主要内容,如果未能解决你的问题,请参考以下文章

Gson解析json字符串

Gson解析json字符串

用Gson按照键值key排序json所有节点

GSON:如何从 Json 中获取不区分大小写的元素?

Android JSON数据解析(GSON方式)

用GSON解析Json格式数据