有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java JSON解析中的NullPointerException

我第一次尝试从web api解析JSON,得到的是NullPointerException。我所做的是下载json。jar文件,并像外部库一样添加它,然后将JSON添加到StringBuffer中,只是为了看看它是否能正常工作—添加系统。出来普林顿。 然后我创建了JSON对象,但不确定参数是否应该是stringBuffer对象? 最后,我尝试创建一个JSON数组并从中搜索字符串“Država”,但随后我得到了这个NullPointerException。 我错在哪里

编辑:我还没有使用Maven

我的代码:

try {   

    double responseCode = conn.getResponseCode();
    BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
    System.out.println("Broj tečajnice = "+ responseCode);

    String inputLine;
    StringBuffer response = new StringBuffer();

    while ((inputLine = in.readLine()) != null) {
        response.append(inputLine);
        System.out.println(inputLine);
    }

    JSONObject obj = new JSONObject(inputLine);

    JSONArray arr = obj.getJSONArray("Država");
    for (int i = 0; i < arr.length(); i++)
    {
        String drzava = arr.getJSONObject(i).getString("Država");
        System.out.println(drzava);
    }
    in.close();
    }
    catch (IOException | JSONException e) {
        e.printStackTrace();
    }

和来自web的JSON:

[{"Broj tečajnice":"188",
"Datum primjene":"30.09.2018",
"Država":"Australija",
"Šifra valute":"036",
"Valuta":"AUD",
"Jedinica":1,
"Kupovni za devize":"4,605078",
"Srednji za devize":"4,618935",
"Prodajni za devize":"4,632792"},

{"Broj tečajnice":"188",
"Datum primjene":"30.09.2018",
"Država":"Kanada",
"Šifra valute":"124",
"Valuta":"CAD",
"Jedinica":1,
"Kupovni za devize":"4,903440",
"Srednji za devize":"4,918195",
"Prodajni za devize":"4,932950"}
...etc...]

例外情况:

java.lang.NullPointerException
at java.io.StringReader.<init>(StringReader.java:50)
at org.json.JSONTokener.<init>(JSONTokener.java:66)
at org.json.JSONObject.<init>(JSONObject.java:420)
at pretvaracValuta.PretvaracController.connection(PretvaracController.java:49)
at pretvaracValuta.PretvaracController.initialize(PretvaracController.java:24)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2548)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3214)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3175)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3148)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3124)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3104)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3097)
at pretvaracValuta.Main.start(Main.java:14)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$106(LauncherImpl.java:863)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$119(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null$117(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$118(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
at com.sun.glass.ui.gtk.GtkApplication.lambda$null$450(GtkApplication.java:139)
at java.lang.Thread.run(Thread.java:748)

共 (3) 个答案

  1. # 1 楼答案

    第一个问题

    将错误的值传递到JSONObject构造函数。看看这段代码:

    String inputLine;
    StringBuffer response = new StringBuffer();
    
    while ((inputLine = in.readLine()) != null) {
        response.append(inputLine);
        System.out.println(inputLine);
    }
    
    JSONObject obj = new JSONObject(inputLine);
    

    只有当inputLine为空时,while循环才会完成,所以最后一行相当于:

    JSONObject obj = new JSONObject(null);
    

    。。。这显然不是你想要的。我想你想要:

    JSONObject obj = new JSONObject(response.toString());
    

    请注意,您可能希望使用StringBuilder而不是StringBuffer,以避免无意义的同步

    下一个问题

    如果JSON实际上是[ ... ]形式,那么它是一个数组,而不是顶层的对象。所以你可能想要:

    JSONArray arr = new JSONArray(response.toString());
    for (int i = 0; i < arr.length(); i++)
    {
        String drzava = arr.getJSONObject(i).getString("Država");
        System.out.println(drzava);
    }
    

    毕竟,如果你看一下你的JSON,它没有Država作为一个数组作为值的属性名

  2. # 2 楼答案

    我认为您对JSonObject使用了错误的输入:

    double responseCode = conn.getResponseCode();
    try (InputStreamReader  sr =new InputStreamReader(conn.getInputStream());
         BufferedReader in = new BufferedReader(sr)){  
    // ^ this is Jdk7+, will close your streams after the block exists, like in finally block 
    
    ...
    
    JSONObject obj = new JSONObject(response.toString()); // pass the input as a String
    
    ....
    }catch (IOException | JSONException e) {
        e.printStackTrace();
    }
    

    变量response以字符串的形式保存输入,而inputLine只保存一行。在最后一次迭代之后,它被设置为null。这将导致NPE

  3. # 3 楼答案

    您需要获取JSONArray,然后迭代它以解析所需的值

    JSONArray array = new JSONArray(inputLine);
    for (int i = 0; i < array.length(); i++) {
       System.out.println(array.get(i).get("Država"));
    }