Gson - 一个场的两个json键

时间:2013-10-12 08:55:55

标签: java json gson

我读过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来完成?

2 个答案:

答案 0 :(得分:1)

一种解决方案可能是写一个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));
    }

}

这就是结果:

  

Box [width = 4,height = 5,depth = 1]

     

Box [width = 4,height = 5,depth = 1]

答案 1 :(得分: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
}