2013-10-12 2 views
1

Я читал документы 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?

+0

Просто, чтобы быть уверенным, что я понимаю вашу проблему. Вы хотите, чтобы десериализовать что-то вроде {«width»: 3, «h»: 4, «d»: 2} или {«w»: 3, «h»: 4, «d»: 2} равномерно в поле? – giampaolo

+0

trapo - да действительно) – jumper0k

ответ

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

Обратите внимание, что ставить Box и BoxAdapter в тот же пакет. Я изменил видимость полей Box, чтобы отобразить их, чтобы избежать использования геттеров/сеттеров. Но вы можете использовать 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]

Смежные вопросы