【问题标题】:Gson - two json keys for a one fieldGson - 一个字段的两个 json 键
【发布时间】:2013-10-12 08:55:54
【问题描述】:

我已阅读 Gson 文档并决定使用它。但我不知道如何为一个字段设置两个不同的 JSON 键。例如,我有:

public class Box {

  @SerializedName("w")
  private int width;

  @SerializedName("h")
  private int height;

  @SerializedName("d")
  private int depth;

}

对于字段 width,如果在 JSON 字符串中找不到 first,我想使用键 w 或替代键 width 对其进行反序列化。

例如,{"width":3, "h":4, "d":2}{"w":3, "h":4, "d":2} 应该可以解析为 Box 类。

我怎样才能使用注释或使用TypedAdapter

【问题讨论】:

  • 只是为了确保我理解您的问题。您是否想将 {"width":3, "h":4, "d":2} 或 {"w":3, "h":4, "d":2} 等内容反序列化到 Box 中?

标签: java json gson


【解决方案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));
    }

}

结果如下:

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

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

【讨论】:

    【解决方案2】:

    更新:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-29
      • 1970-01-01
      • 2016-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-05
      • 2012-04-13
      相关资源
      最近更新 更多