NullPointerException : JSON Parsing in JAVA using GSON
gson, java, json, nullpointerexception
Solution
SOLUTION:
You are using more classes than necessary to parse the JSON response! You can delete your classes `ListTeleServices` and `TeleService` and keep only your `Record` class.
Gson gson = new Gson();
Type mapOfMapsType = new TypeToken<Map<String, Map<String, Record>>>() {}.getType();
Map<String, Map<String, Record>> map = gson.fromJson(br, mapOfMapsType);
Finally, in order to get the method name, you have to use:
String methodName = map.get("Teleservice_2").get("Record_33").getMethodName();
EXPLANATION:
When you use your class `ListTeleServices` to parse the JSON here:
ListTeleServices teleservices = gson.fromJson(br, ListTeleServices.class);
What Gson does is to analise the class `ListTeleServices` and compare it with the JSON response, so it says:
You passed a class `ListTeleServices.class`, and the JSON response starts with an object `{}`... so far everything is OK!
Then it continues parse the JSON, and:
- In the class `ListTeleServices` it finds an attribute `listTeleServices` which is some object (doesn't mind the type for the moment).
- However, in the JSON response it finds three elements `"Teleservice_1"`, `"Teleservice_2"` and `"Teleservice_3"`, but none of them has the same name `listTeleServices`, so Gson skip all these values and assigns `null` to the attribute `listTeleServices`...
Remember that Gson needs the names in the JSON response to be the same that those in the class you are using to parse the response.
On the other hand, if you use directly a `Map<String, Map<String, Record>>`, Gson see:
You passed the type of `Map<String, Map<String, Record>>`, and the JSON response starts with an object `{}`... so far everything is OK! (Remember a `Map` is just an object)
Then it continues parse the JSON, and:
- In `Map<String, Map<String, Record>>` it see that there must be some pairs of key (string) and value (some object).
- And in the JSON response it finds exactly that, some pairs of strings `"Teleservice_1"`, `"Teleservice_2"` and `"Teleservice_3"`, and some objects `{}`, so it can keep parsing happily...
P.S: To go further, note that you could have in your class `ListTeleServices` these attributes:
private HashMap<String, Record> Teleservice_1;
private HashMap<String, Record> Teleservice_2;
private HashMap<String, Record> Teleservice_3;
And it would work well, but this way you can't have an arbitrary number of teleservice ojects...
And by the way, I've also realised other error: in your `Response` class, the attribute name `method_parameters` doesn't match the name of the field in the JSON response, which is `method_params`. You can either change the attribute name or use the annotation:
@SerializedName("method_params")
private Object[] method_parameters;
Problem
I want to parse a JSON File through java using the Api GSON to get the last fields of the JSON file : descriptor.json : ``` { "Teleservice_1" : { "Record_1" : { "method_name" : "mehdi", "method_params": ["param1",2,"param3"] }, "Record_2" : { "method_name" : "mkyong", "method_params": [3,"param2"] }, "Record_3" : { "method_name" : "amine", "method_params": [3,"param1","param2"] } }, "Teleservice_2" : { "Record_11" : { "method_name" : "mehdi1", "method_params": ["param11",22,"param33"] }, "Record_22" : { "method_name" : "mkyong1", "method_params": [33,"param22"] }, "Record_33" : { "method_name" : "amine1", "method_params": [33,"param11","param22"] } }, "Teleservice_3" : { "Record_111" : { "method_name" : "mehdi2", "method_params": ["param111",222,"param333"] }, "Record_222" : { "method_name" : "mkyong2", "method_params": [333,"param222"] }, "Record_333" : { "method_name" : "amine2", "method_params": [333,"param111","param222"] } } } ``` ListTeleServices.java : ``` import java.util.HashMap; public class ListTeleServices { private HashMap<String, TeleService> listTeleServices; public ListTeleServices() { } public TeleService getTeleService(String teleserviceName) { if(this.listTeleServices.get(teleserviceName) != null) return this.listTeleServices.get(teleserviceName); else return null; } } ``` TeleService.java : ``` import java.util.HashMap; public class TeleService { private HashMap<String, Record> listRecords; public TeleService() { } public Record getRecord(String recordName) { if(this.listRecords.get(recordName) != null) return this.listRecords.get(recordName); else return null; } } ``` Record.java : ``` public class Record { private String method_name; private Object[] method_parameters; public Record(String methodName, Object[] methodParameters) { this.method_name = new String(methodName); this.method_parameters = methodParameters; } public String getMethodName() { return this.method_name; } public Object[] getMethodParameters() { return this.method_parameters; } public void setMethodName(String methodName) { this.method_name = methodName; } public void setMethodParameters(Object[] methodParameters) { this.method_parameters = methodParameters; } } ``` And finally my parser class, JSONMainParse.java : ``` import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import com.google.gson.Gson; public class JSONMainParse { public static void main(String[] args) throws FileNotFoundException { BufferedReader br = new BufferedReader(new FileReader("/Users/Mehdi/Desktop/descriptor.json")); Gson gson = new Gson(); ListTeleServices teleservices = gson.fromJson(br, ListTeleServices.class); String methodName = teleservices.getTeleService("Teleservice_2").getRecord("Record_33").getMethodName(); System.out.println(methodName); } } ``` It seems correct to me, and it should display : "amine1" but it gives me a nullPointerException at : ListTeleServices.getTeleService(ListTeleServices.java:12) which is : ``` if(this.listTeleServices.get(teleserviceName) != null) ``` and at JSONMainParse.main(JSONMainParse.java:15) which is : ``` String methodName = teleservices.getTeleService("Teleservice_2").getRecord("Record_33").getMethodName(); ``` Do you have any idea about this ? Thank you :)