NullPointerException: синтаксический анализ JSON в JAVA с использованием GSON
Я хочу проанализировать файл JSON через java с помощью Api GSON, чтобы получить последние поля файла JSON:
дескриптор.в 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;
}
}
Телесервиса.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;
}
}
запись.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;
}
}
и, наконец, мой класс парсера,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);
}
}
кажется правильно для меня, и он должен отображать: "amine1", но это дает мне nullPointerException at:
ListTeleServices.getTeleService (ListTeleServices.java: 12) что :
if(this.listTeleServices.get(teleserviceName) != null)
и в JSONMainParse.main (JSONMainParse.java: 15) что :
String methodName = teleservices.getTeleService("Teleservice_2").getRecord("Record_33").getMethodName();
у вас есть какие-либо идеи по этому поводу ? Спасибо :)
3 ответов
устранение:
вы используете больше классов, чем необходимо для анализа ответа JSON! Вы можете удалить свои классы ListTeleServices
и TeleService
и оставить только Record
класса.
Gson gson = new Gson();
Type mapOfMapsType = new TypeToken<Map<String, Map<String, Record>>>() {}.getType();
Map<String, Map<String, Record>> map = gson.fromJson(br, mapOfMapsType);
наконец, чтобы получить имя метода, вы должны использовать:
String methodName = map.get("Teleservice_2").get("Record_33").getMethodName();
объяснение:
когда вы используете ваш класс ListTeleServices
чтобы разобрать JSON здесь:
ListTeleServices teleservices = gson.fromJson(br, ListTeleServices.class);
что Дсын это эналайз класс ListTeleServices
и сравните его с ответом JSON, поэтому он говорит:
вы прошли класс
ListTeleServices.class
, и ответ JSON начинается с объекта{}
... пока все в порядке!-
затем он продолжает анализировать JSON и:
- в классе
ListTeleServices
находит атрибутlistTeleServices
что какой-то объект (не вида на данный момент). - однако в ответе JSON он находит три элемента
"Teleservice_1"
,"Teleservice_2"
и"Teleservice_3"
, но ни один из них не имеет того же имениlistTeleServices
, поэтому Gson пропускает все эти значения и присваиваетnull
атрибутlistTeleServices
...
- в классе
помните, что Gson нуждается в именах в ответе JSON, чтобы быть тем же, что и в классе, который вы используете для анализа ответа.
С другой стороны, если вы используете непосредственно Map<String, Map<String, Record>>
, Дсын см.:
вы прошли типа
Map<String, Map<String, Record>>
, и ответ JSON начинается с объекта{}
... пока все в порядке! (ПомнюMap
- это просто объект)-
затем он продолжает анализировать JSON и:
- на
Map<String, Map<String, Record>>
он видит, что должны быть некоторые пары ключа (строка) и значения (некоторый объект). - и в ответе JSON он находит именно это, некоторые пары строк
"Teleservice_1"
,"Teleservice_2"
и"Teleservice_3"
, и некоторые объекты{}
, поэтому он может продолжать разбор счастливо...
- на
П. С.: чтобы пойти дальше, обратите внимание, что вы могли бы иметь в своем классе ListTeleServices
этих атрибутов:
private HashMap<String, Record> Teleservice_1;
private HashMap<String, Record> Teleservice_2;
private HashMap<String, Record> Teleservice_3;
и это будет работать хорошо, но таким образом вы не можете иметь произвольное количество объектов Телесервиса...
и кстати, я понял другая ошибка: в Response
класс, имя атрибута method_parameters
не соответствует имени Поля в ответе JSON, которая составляет method_params
. Вы можете изменить имя атрибута или использовать аннотации:
@SerializedName("method_params")
private Object[] method_parameters;
инициализации
private HashMap<String, TeleService> listTeleServices;
as
private HashMap<String, TeleService> listTeleServices = new HashMap<>();
в текущем коде вы пытаетесь вызвать get()
на null
ссылка на объект, который бросает NullPointerException , а ты попытка вызвать метод экземпляра для нулевого объекта.
изменить это:
private HashMap<String, TeleService> listTeleServices;
этой
private HashMap<String, TeleService> listTeleServices = new HashMap<String,TeleService>();