2015-02-14 4 views
4

У меня есть формат JSON выглядеть следующим образом:уровень Пропустить когда синтаксический анализ с Gson

{ 
"root": { 
    "user": { 
     "name":"Name", 
     "age":99, 
     "another_obj": { 
      "f1":"abc", 
      "f2":1 
     } 
    } 
}, 
"result_code": 0 
} 

Я создаю некоторые модели выглядят как:

class User { 
private String name; 
private int age; 
@SerializedName("detail") 
private Detail 
} 

class Detail{ 
    // Define something. 
} 

наконец создать имя класса UserWapper.

class UserWapper { 
@SerializedName("root") 
private User user; 
} 

Для разбора JSON:

String json = "STRING_JSON_ABOVE"; 
Gson gson = new Gson(); 
UserWrapper uw = gson.fromJson(json, UserWrapper.class); 

Но тока я не хочу создать класс-обертку. Потому что у меня много классов. Если создать WrapperClass ->: |

Я хочу сделать что-то вроде:

User u = gson.fromJson(json, User.class). 

(Примечание: я не могу изменить формат JSON данных с сервера Я также Гг поиска что-то пользовательские gson адаптер, но я не найти способ для Скипа. «уровень» другого поля).

ответ

2

Если вы не хотите, класс-оболочку, вы можете разобрать вашу строку JSON в JsonObject, а затем получить его user объекта и десериализации объекта пользователя к экземпляру вашего User класса.

Try ниже код:

String json = "{\"root\":{\"user\":{\"name\":\"Name\",\"age\":99,\"another_obj\":{\"f1\":\"abc\",\"f2\":1}}},\"result_code\":0}"; 
Gson gson = new Gson(); 
JsonObject jsonObject = gson.fromJson(json, JsonObject.class); 
User u = gson.fromJson(((JsonObject)jsonObject.get("root")).get("user"), User.class); 

System.out.println("user.name: " + u.name); 
System.out.println("user.age: " + u.age); 

Выход:

user.name: Имя
user.age: 99

+0

Hi, как u смотреть. Нам еще нужно добавить один шаг, чтобы получить строковый внутренний «root» obj. Можем ли мы сделать это простым, чем: Пользователь u = gson.fromJson (json, User.class). – quangson91

+0

@ quangson91 no, это невозможно, если вы не хотите писать пользовательский TypeAdapter или JsonSerialzer, что затруднит его работу. Простое решение - написать оболочку или получить внутренний элемент json и проанализировать его, как я описал в своем ответе. Это самый простой способ. – Devrim

+0

Вы используете Google Map Api? Я часто вижу, что ответ данных будет оберткой с «корневым» объектом: | (Я думаю, что это очень сильно застряло, если мы создадим много класс Wrapper). – quangson91

0

Я просто реализован другой подход: Аннотировать JsonAdapter в поле, которое содержит только объект-оболочку. JsonAdapter фактически TypeAdapterFactory, как это:

/** 
* Use with {@link com.google.gson.annotations.JsonAdapter} on fields to skip a single pseudo object 
* for map-like types. 
*/ 
public class UnwrappingJsonAdapter implements TypeAdapterFactory { 

    @Override 
    public <T> TypeAdapter<T> create(final Gson gson, final TypeToken<T> type) { 
     return new TypeAdapter<T>() { 

      @Override 
      public void write(JsonWriter out, T value) throws IOException { 
       out.beginObject(); 
       out.name(type.getType().getClass().getSimpleName()); 
       gson.toJson(value, type.getType(), out); 
       out.endObject(); 
      } 

      @Override 
      public T read(JsonReader in) throws IOException { 
       in.beginObject(); 
       in.nextName(); 
       final T object = gson.fromJson(in, type.getType()); 
       in.endObject(); 
       return object; 
      } 
     }; 
    } 
} 

Это работает для меня. Другие могут захотеть настроить имя синтезированного объекта в сериализации. Также десериализация не очень надежна или гибка.

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