java - 空指针异常 : JSON Parsing in JAVA using GSON

标签 java json nullpointerexception gson

我想使用 Api GSON 通过 java 解析 JSON 文件以获取 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();

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

最佳答案

解决方案:

您使用的类比解析 JSON 响应所必需的多!您可以删除您的类(class) ListTeleServicesTeleService只保留你的 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();

说明:

当你使用你的类(class)时ListTeleServices在此处解析 JSON:

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

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

  1. 您通过了类(class) 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. 您传递了 Map<String, Map<String, Record>> 的类型,并且 JSON 响应以对象 {} 开头...到目前为止一切正常! (记住 Map 只是一个对象)

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

    • Map<String, Map<String, Record>>它看到必须有一些键(字符串)和值(某个对象)对。
    • 在 JSON 响应中,它准确地找到了一些字符串对 "Teleservice_1" , "Teleservice_2""Teleservice_3"和一些对象 {} , 所以它可以继续愉快地解析...

P.S:更进一步,请注意您可以在类里面使用 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;

关于java - 空指针异常 : JSON Parsing in JAVA using GSON,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16416965/

相关文章:

java - 如何在Java中用字节构建int值?

java - NullPointerException 堆栈跟踪在没有调试代理的情况下不可用

java - 如何使用 setOnClickListener 将 ListView 数据从一个 Activity 获取到另一个 Activity

使用 ex.getMessage() 打印时,androidHttpTransport.call(...,...) 抛出空异常

JAVA:虚拟鼠标

java - 忽略依赖 jar 中的 Jackson 2.0 注释

python - 带有 xmltodict unparse() 函数的 ValueError - Python 3

java - 如何从 Java 中的 HTTP 请求中获取 JSON 对象

Java,Tomcat 6 : saving files to local HD

java - 解析 JSONObjects 和 JSONArrays 的最佳方式