NullPointerException:使用GSON在JAVA中进行JSON解析
我想使用Api GSON通过java解析JSON文件以获取JSON文件的最后一个字段:
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 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 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; } }
最后我的解析器类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 :
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();
你对此有什么想法吗? 谢谢 :)
解:
您正在使用比解析JSON响应所需的更多类! 您可以删除ListTeleServices
和TeleService
类,只保留Record
类。
Gson gson = new Gson(); Type mapOfMapsType = new TypeToken
最后,为了获取方法名称,您必须使用:
String methodName = map.get("Teleservice_2").get("Record_33").getMethodName();
说明:
当您使用类ListTeleServices
在此处解析JSON时:
ListTeleServices teleservices = gson.fromJson(br, ListTeleServices.class);
Gson所做的是分析ListTeleServices
类并将其与JSON响应进行比较,因此它说:
-
你传递了一个
ListTeleServices.class
类,JSON响应以一个对象{}
……到目前为止一切正常! -
然后它继续解析JSON,并且:
- 在类
ListTeleServices
它找到一个属性listTeleServices
,它是一个对象(暂时不介意类型)。 - 但是,在JSON响应中,它找到三个元素
"Teleservice_1"
,"Teleservice_2"
和"Teleservice_3"
,但它们都没有相同的名称listTeleServices
,因此Gson跳过所有这些值并将null
赋给属性listTeleServices
…
- 在类
请记住,Gson需要JSON响应中的名称与您用于解析响应的类中的名称相同。
另一方面,如果直接使用Map
,Gson请参阅:
-
你传递了
Map
,JSON响应以对象> {}
……到目前为止一切正常! (记住Map
只是一个对象) -
然后它继续解析JSON,并且:
- 在
Map
它看到必须有一些键(字符串)和值(某个对象)。> - 在JSON响应中,它确切地找到了一些字符串
"Teleservice_1"
,"Teleservice_2"
和"Teleservice_3"
,以及一些对象{}
,因此它可以保持愉快的解析…
- 在
PS:更进一步,请注意您可以在类ListTeleServices
以下属性:
private HashMap Teleservice_1; private HashMap Teleservice_2; private HashMap Teleservice_3;
它会很好用,但这样你就不能拥有任意数量的远程服务对象……
顺便说一下,我还意识到了其他错误 :在您的Response
类中,属性名称method_parameters
与JSON响应中的字段名称不匹配,即method_params
。 您可以更改属性名称或使用注释:
@SerializedName("method_params") private Object[] method_parameters;
初始化
private HashMap listTeleServices;
如
private HashMap listTeleServices = new HashMap<>();
在当前代码中,您尝试在null
对象引用上调用get()
,这会引发NullPointerException ,因为您尝试在null对象上调用实例方法。
改变这个:
private HashMap listTeleServices;
对此
private HashMap listTeleServices = new HashMap();