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响应所需的更多类! 您可以删除ListTeleServicesTeleService类,只保留Record类。

 Gson gson = new Gson(); Type mapOfMapsType = new TypeToken>>() {}.getType(); Map> map = gson.fromJson(br, mapOfMapsType); 

最后,为了获取方法名称,您必须使用:

 String methodName = map.get("Teleservice_2").get("Record_33").getMethodName(); 

说明:

当您使用类ListTeleServices在此处解析JSON时:

 ListTeleServices teleservices = gson.fromJson(br, ListTeleServices.class); 

Gson所做的是分析ListTeleServices类并将其与JSON响应进行比较,因此它说:

  1. 你传递了一个ListTeleServices.class类,JSON响应以一个对象{} ……到目前为止一切正常!

  2. 然后它继续解析JSON,并且:

    • 在类ListTeleServices它找到一个属性listTeleServices ,它是一个对象(暂时不介意类型)。
    • 但是,在JSON响应中,它找到三个元素"Teleservice_1""Teleservice_2""Teleservice_3" ,但它们都没有相同的名称listTeleServices ,因此Gson跳过所有这些值并将null赋给属性listTeleServices

请记住,Gson需要JSON响应中的名称与您用于解析响应的类中的名称相同。

另一方面,如果直接使用Map> ,Gson请参阅:

  1. 你传递了Map> ,JSON响应以对象{} ……到目前为止一切正常! (记住Map只是一个对象)

  2. 然后它继续解析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();