2014-09-07 5 views
54

Есть ли способ в Gson сопоставить несколько полей JSON одной переменной-члену объекта Java?Несколько GSON @SerializedName в поле?

Скажем, у меня есть класс Java ...

public class MyClass { 
    String id; 
    String name; 
} 

Я хочу использовать этот один класс с двумя различными службами. Тем не менее, эти две услуги отличаются тем, как они возвращают свои данные ...

{ "id": 2341, "person": "Bob" } 

... и ...

{ "id": 5382, "user": "Mary" } 

... соответственно.

Есть ли способ сопоставить поляи "user" в строке JSON с полем name в объекте Java?

. (Примечание: я только когда-либо необходимо преобразовать из JSON строки в объект Java - никогда наоборот)

+0

Вот простой и Совершенная объяснение https://futurestud.io/tutorials/gson-model-annotations-multiple-deserialization-names-with-serializedname –

ответ

20

Это не поддерживается определить несколько @SerializedName аннотации к полю на Gson.

Причина: По умолчанию десериализации управляется с LinkedHashMap и ключи определяются имена полей входящего JSon в (имена полей не принято класса или serializedNames) и есть 12:59 отображение а. Вы можете увидеть реализацию (как работает десериализация) в классе ReflectiveTypeAdapterFactory класса класса Adapter<T>read(JsonReader in).

Решение: Вы можете написать пользовательский TypeAdapter который обрабатывает name, person и user JSon теги и отображает их на поле имени пользовательского класса MyClass:

class MyClassTypeAdapter extends TypeAdapter<MyClass> { 

    @Override 
    public MyClass read(final JsonReader in) throws IOException { 
     final MyClass myClassInstance = new MyClass(); 

     in.beginObject(); 
     while (in.hasNext()) { 
      String jsonTag = in.nextName(); 
      if ("id".equals(jsonTag)) { 
       myClassInstance.id = in.nextInt(); 
      } else if ("name".equals(jsonTag) 
        || "person".equals(jsonTag) 
        || "user".equals(jsonTag)) { 
       myClassInstance.name = in.nextString(); 
      } 
     } 
     in.endObject(); 

     return myClassInstance; 
    } 

    @Override 
    public void write(final JsonWriter out, final MyClass myClassInstance) 
      throws IOException { 
     out.beginObject(); 
     out.name("id").value(myClassInstance.id); 
     out.name("name").value(myClassInstance.name); 
     out.endObject(); 
    } 
} 

Контрольный пример:

String jsonVal0 = "{\"id\": 5382, \"user\": \"Mary\" }"; 
    String jsonVal1 = "{\"id\": 2341, \"person\": \"Bob\"}"; 

    final GsonBuilder gsonBuilder = new GsonBuilder(); 
    gsonBuilder.registerTypeAdapter(MyClass.class, new MyClassTypeAdapter()); 
    final Gson gson = gsonBuilder.create(); 

    MyClass myClassInstance0 = gson.fromJson(jsonVal0, MyClass.class); 
    MyClass myClassInstance1 = gson.fromJson(jsonVal1, MyClass.class); 

    System.out.println("jsonVal0 :" + gson.toJson(myClassInstance0)); 
    // output: jsonVal0 :{"id":5382,"name":"Mary"} 

    System.out.println("jsonVal1 :" + gson.toJson(myClassInstance1)); 
    // output: jsonVal1 :{"id":2341,"name":"Bob"} 

Examples about TypeAdapters.

Редактировать 2016.04.06: Поскольку @Mathieu Castets написал в ответ, он поддерживается сейчас. (Это правильный ответ на этот вопрос.)

общественного аннотация String [] альтернативные
Возвращает: альтернативные имена поле, когда он десериализируется
По умолчанию: {}

+0

Вот простое и идеальное объяснение https://futurestud.io/tutorials/gson-model-annotations-multiple-deserialization-names-with-serializedname –

130

В октябре 2015 года Gson version 2.4 (changelog) добавлена ​​возможность использования альтернативных/множественных имен для @SerializedName при десериализации. Больше не нужно настраивать TypeAdapter!

Использование:

@SerializedName(value="name", alternate={"person", "user"}) 

https://google.github.io/gson/apidocs/com/google/gson/annotations/SerializedName.html

+0

Отлично. Спасибо. – Mulgard

+1

Сохраняет меня от другого глупого обходного пути и некоторых условий. Спасибо :) –

+0

Вот простое и прекрасное объяснение https://futurestud.io/tutorials/gson-model-annotations-multiple-deserialization-names-with-serializedname –

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