2012-05-19 1 views
1

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

{ 
    "Speidy": { 
     "factionId": "2", 
     "role": "ADMIN", 
     "title": "", 
     "power": 9.692296666666667, 
     "powerBoost": 0.0, 
     "lastPowerUpdateTime": 1337023306922, 
     "lastLoginTime": 1337023306922, 
     "chatMode": "PUBLIC" 
    }, 
    "ShadowSlayer272": { 
     "factionId": "2", 
     "role": "NORMAL", 
     "title": "", 
     "power": 0.8673466666666667, 
     "powerBoost": 0.0, 
     "lastPowerUpdateTime": 1336945426926, 
     "lastLoginTime": 1336945426926, 
     "chatMode": "PUBLIC" 
    }, 

Мой вопрос является первым «узел» является полностью случайным, то есть, как я могу сделать файл POJO для него, если он каждый раз разный?

Мой файл POJO для суб-данных, как это:

public class Node { 
    private int factionId = 0; 
    private String role = ""; 
    private String title = ""; 
    private double power = 0.0; 
    private double powerBoost = 0.0; 
    private int lastPowerUpdateTime = 0; 
    private int lastLoginTime = 0; 
    private String chatMode = ""; 
} 

И тогда мой другой файл POJO это:

public class Container { 
    private List<Node> nodes; //What should nodes be for GSON to get each random one? 

    public List<Node> getNodes() { 
     return nodes; 
    } 
} 

Я ценю помощь, спасибо.

UPDATE

Я попытался изменить List к Map как таковой:

public class Container { 
    private Map<String,Node> nodes; 

    public Map<String,Node> getNodes() { 
     return nodes; 
    } 

При сохранении файла узла то же самое. Строкой будет тогда имя свойства i.e Speidy или ShadowSlayer272. Тем не менее, gson никогда ничего не делает с узлами, и когда я пытаюсь и getNodes(), он возвращает объект null.

Спасибо за помощь.

+0

Либо карта nodes' 'в' Container' или заказ 'TypeAdapter' может быть то, что вы находясь в поиске. –

+0

Я попытался добавить карту, но она всегда была бы нулевой после попытки десериализации. –

ответ

2

Вы указываете то, что кажется именем, которое вы, возможно, предназначили для представления значения, как имя свойства для объекта. Вместо этого включите имя внутри строки JSON и присвойте ему имя свойства, которое будет фактически отображаться как приватная переменная (с геттерами и сеттерами) в вашем классе Java Node.

С помощью этого места вы должны затем десериализовать JSON обратно в объект. Кроме того, поскольку на стороне сервера вы представляете коллекцию узлов как список, я преобразовал JSON в массив, содержащий два объекта. В JavaScript, вы бы получить доступ к ним, как и node[0].namenode[1].name, который бы приравнять к nodes.get(0).getName() на стороне сервера:

[ 
    { 
     "name" : "Speidy", 
     "factionId": "2", 
     "role": "ADMIN", 
     "title": "", 
     "power": 9.692296666666667, 
     "powerBoost": 0.0, 
     "lastPowerUpdateTime": 1337023306922, 
     "lastLoginTime": 1337023306922, 
     "chatMode": "PUBLIC" 
    }, 
    { 
     "name" : "ShadowSlayer272", 
     "factionId": "2", 
     "role": "NORMAL", 
     "title": "", 
     "power": 0.8673466666666667, 
     "powerBoost": 0.0, 
     "lastPowerUpdateTime": 1336945426926, 
     "lastLoginTime": 1336945426926, 
     "chatMode": "PUBLIC" 
    } 
] 

public class Node { 
    private String name = ""; 

    private int factionId = 0; 
    private String role = ""; 
    private String title = ""; 
    private double power = 0.0; 
    private double powerBoost = 0.0; 
    private int lastPowerUpdateTime = 0; 
    private int lastLoginTime = 0; 
    private String chatMode = ""; 
} 

С учетом сказанного, если вы действительно должны использовать имя в качестве имени свойства, то рассмотрите десериализацию JSON вместо HashMap вместо списка. Списки обычно сопоставляются с массивами JSON, тогда как Карты обычно лучше подходят для представления нескольких объектов JSON внутри родительского объекта.

+0

Можете ли вы предоставить мне пример кода для использования имени в качестве имени свойства? Я довольно новичок в GSON, и это очень запутывает меня. Спасибо за помощь. Я пробовал частную карту узлов; и все еще не удалось. –

+0

Билли, почему бы вам не обновить свой вопрос с помощью кода, который вы попробовали. Кроме того, пожалуйста, укажите полученные сообщения об ошибках. Используйте ссылку ** edit ** под вопросом, чтобы добавить к ней дополнительные сведения. – jmort253

+0

Хорошо. Я использую stackoverflow. –

1

Если есть контроль формат JSON, я предлагаю the overall list structure that jmort253 suggests in his answer, т.е. [{"name":"Speidy", ... },{"name":"ShadowSlayer272", ... }].

Если вы не имеете никакого контроля над сгенерированной JSON, вот два пути отображающих JSON фрагмента код, как в вашем вопросе {"Speidy":{ ... },"ShadowSlayer272":{ ... }} с Gson:

  • Без вашего Container класс и немного немного TypeToken вуду:

    // Ask Gson to deserialize the JSON snippet into a Map<String, Node>. 
    Type type = new TypeToken<Map<String, Node>>() {}.getType(); 
    Map<String, Node> nodes = gson.fromJson(json, type); 
    
  • С вашего Container класса и пользовательские JsonDeserializer:

    class ContainerDeserializer implements JsonDeserializer<Container> { 
        public Container deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) 
         throws JsonParseException { 
        List<Node> nodes = new ArrayList<Node>(); 
        JsonObject players = json.getAsJsonObject(); 
        for (Entry<String, JsonElement> player : players.entrySet()) { 
         String playerName = player.getKey(); 
         JsonElement playerData = player.getValue(); 
         // Use Gson to deserialize all fields except 
         // for the name into a Node instance ... 
         Node node = context.deserialize(playerData, Node.class); 
         node.name = playerName; // ... then set the name. 
         nodes.add(node); 
        } 
        return new Container(nodes); 
        } 
    } 
    

    Это предполагает конструктор как Container(List<Node>) и позволяет Container экземпляров неизменяемыми, которые, как правило, хорошая вещь.

    Регистрация и использовать пользовательские сериалайзер вроде этого:

    GsonBuilder builder = new GsonBuilder(); 
    // Tell Gson to use the custom ContainerDeserializer whenever 
    // it's asked for a Container instance. 
    builder.registerTypeAdapter(Container.class, new ContainerDeserializer()); 
    Gson gson = builder.create(); 
    
    // Ask Gson to create Container instance from your JSON snippet. 
    Container container = gson.fromJson(json, Container.class); 
    
+0

Спасибо, Филипп! –