I\'m having trouble reading a JSON file into a POJO. Let me give you a snippet of what my JSON file entails:
{
\"Speidy\": {
\"factionId\": \"2\",
You're listing what appears to be a name, which you possibly meant to represent a value, as a property name for an object. Instead, include the name inside the JSON string and assign it a property name that will actually appear as a private variable (with getters and setters) in your Java Node class.
With this in place, you should then be able to deserialize your JSON back into an object. Also, since on the server-side you're representing the Node collection as a List, I converted the JSON to an array that contains two objects. In JavaScript, you'd access them as node[0].name
and node[1].name
, which would equate to nodes.get(0).getName()
on the server-side:
[
{
"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 = "";
}
With that said, if you really do need to use the name as a property name, then consider deserializing the JSON to a HashMap instead of a List. Lists generally map to JSON arrays, whereas Maps generally are better suited towards representing several JSON objects inside a parent object.
If you do have control the format of the JSON, I suggest the overall list structure that jmort253 suggests in his answer, i.e. [{"name":"Speidy", ... },{"name":"ShadowSlayer272", ... }]
.
If you have no control over the generated JSON, here's two ways to map a JSON snippet like the one in your question {"Speidy":{ ... },"ShadowSlayer272":{ ... }}
with Gson:
Without your Container
class and a little bit of TypeToken
voodoo:
// 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);
With your Container
class and a custom 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);
}
}
This assumes a constructor like Container(List<Node>)
and allows Container
instances to be immutable which is usually a Good Thing.
Register and use the custom serializer like this:
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);