NullPointerException:使用 GSON 在 JAVA 中解析 JSON [英] NullPointerException : JSON Parsing in JAVA using GSON

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

问题描述

我想使用 Api GSON 通过 java 解析 JSON 文件以获取 JSON 文件的最后一个字段:

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;
    }
}

最后是我的解析器类,JSONMainParse.java :

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);
    }
}

对我来说似乎是正确的,它应该显示:amine1",但它给了我一个 nullPointerException 在:

It seems correct to me, and it should display : "amine1" but it gives me a 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();

你对此有什么想法吗?谢谢:)

Do you have any idea about this ? Thank you :)

推荐答案

解决方案:

您使用的类比解析 JSON 响应所需的类多!您可以删除您的 ListTeleServicesTeleService 类,而只保留您的 Record 类.

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();

<小时>

解释:

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


EXPLANATION:

When you use your class ListTeleServices to parse the JSON here:

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

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

What Gson does is to analise the class ListTeleServices and compare it with the JSON response, so it says:

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

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

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

Then it continues parse the JSON, and:

  • ListTeleServices 类中,它找到一个属性listTeleServices,它是某个对象(暂时不介意类型).
  • 然而,在 JSON 响应中,它找到了三个元素 "Teleservice_1""Teleservice_2""Teleservice_3",但没有一个具有相同的名称 listTeleServices,因此 Gson 跳过所有这些值并将 null 分配给属性 listTeleServices...
  • 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...

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

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.

另一方面,如果你直接使用一个Map>,Gson看到:

On the other hand, if you use directly a Map<String, Map<String, Record>>, Gson see:

  1. 您传递了 Map 的类型,并且 JSON 响应以对象 {} 开头.. 到目前为止一切正常!(记住 Map 只是一个对象)

  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)

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

Then it continues parse the JSON, and:

  • Map 中,它看到必须有一些键(字符串)和值(某个对象)对.
  • 在 JSON 响应中,它准确地找到了一些字符串对 "Teleservice_1""Teleservice_2""Teleservice_3",和一些对象{},所以它可以继续愉快地解析...
  • 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: 要更进一步,请注意您可以在类 ListTeleServices 中具有以下属性:

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

顺便说一下,我还发现了其他错误:在您的 Response 类中,属性名称 method_parameters 不匹配JSON 响应中字段的名称,即 method_params.您可以更改属性名称或使用注释:

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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆