本文介绍了NullPointerException:使用GSON在JAVA中解析JSON的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


$ b

descriptor.json:

我想通过使用Api GSON的java解析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;
$ b $公共ListTeleServices(){

}

公共TeleService getTeleService(String teleserviceName){
if(this.listTeleServices.get teleserviceName)!= null)
返回this.listTeleServices.get(teleserviceName);
else
返回null;
}
}

TeleService.java

  import java.util.HashMap; 

public class TeleService {

private HashMap< String,Record> listRecords;

public TeleService(){

}

记录getRecord(String recordName){
if(this.listRecords.get recordName)!= null)
返回this.listRecords.get(recordName);
else
返回null;
}
}

Record.java:

  public class Record {

private String method_name;
private Object [] method_parameters;
$ b $ 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 (新的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);


$ / code>

这对我来说似乎是正确的,它应该显示: amine1,但它给了我一个 nullPointerException
$ b 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 并仅保留您的记录 class。

  Gson gson = new Gson(); 
类型mapOfMapsType = new TypeToken< Map< String,Map< String,Record>>>(){} .getType();
地图< 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); 

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< String,Map< String,Record>> ,Gson请参阅:


  1. 您已通过地图< String,Map< String,Record> > ,并且JSON响应以对象 {} 开头......迄今为止一切正常! (记住 Map 只是一个对象)

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




    • 在 Map< String,Map< String,Record>> 必须有一些关键字(字符串)和值(一些对象)。

    • 在JSON响应中,它精确地找到了一些字符串Teleservice_1,Teleservice_2 和Teleservice_3和一些对象 {} ,所以它可以保持解析愉快地...
    • 此外,请注意,您可以在您的课程 ListTeleServices 这些属性中:

       私人HashMap< String,Record> Teleservice_1; 
      私有HashMap< String,Record> Teleservice_2;
      私有HashMap< String,Record> Teleservice_3;

      它可以很好地工作,但这种方式你不能拥有任意数量的远程服务项目。 ..






      顺便说一句,我也意识到其他错误: 响应类,属性名称 method_parameters 与JSON响应中字段的名称不匹配, code> method_params 。您可以更改属性名称或使用注释:

      $ b $ p code $ @SerializedName(method_params)
      private Object [ ] method_parameters;


      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 :)

      解决方案

      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:

      1. You passed a class ListTeleServices.class, and the JSON response starts with an object {}... so far everything is OK!

      2. 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:

      1. 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)

      2. 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;
      

      这篇关于NullPointerException:使用GSON在JAVA中解析JSON的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-18 21:45
查看更多