Reputation:
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 :)
Upvotes: 9
Views: 13476
Reputation: 18751
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();
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:
ListTeleServices
it finds an attribute listTeleServices
which is some object (doesn't mind the type for the moment). "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:
Map<String, Map<String, Record>>
it see that there must be some pairs of key (string) and value (some object). "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;
Upvotes: 8
Reputation: 49432
Initialize the
private HashMap<String, TeleService> listTeleServices;
as
private HashMap<String, TeleService> listTeleServices = new HashMap<>();
In your current code , you are trying to invoke get()
on the null
object reference, which throws NullPointerException , as you are trying to invoke instance method on a null object.
Upvotes: 2
Reputation: 12524
change this:
private HashMap<String, TeleService> listTeleServices;
to this
private HashMap<String, TeleService> listTeleServices = new HashMap<String,TeleService>();
Upvotes: 2