Search code examples
javajsonapitwitchminimal-json

Getting a Json information


I am coding in Java and I'm using the minimal-json library. I am trying to get some information from a json text (idk if it's an array).

I'm trying to access the "game" value inside "stream", but I always get a crash by nullpointer or a parseexception.

Here is the json string I'm trying to get (From the Twitch Api):

{"_links":{"self":"https://api.twitch.tv/kraken/streams/hackerc0w","channel":"https://api.twitch.tv/kraken/channels/hackerc0w"},"stream":{"_id":13817896816,"game":"Programming","viewers":13,"created_at":"2015-04-01T13:54:54Z","video_height":1080,"average_fps":59.9235368156,"_links":{"self":"https://api.twitch.tv/kraken/streams/hackerc0w"},"preview":{"small":"http://static-cdn.jtvnw.net/previews-ttv/live_user_hackerc0w-80x45.jpg","medium":"http://static-cdn.jtvnw.net/previews-ttv/live_user_hackerc0w-320x180.jpg","large":"http://static-cdn.jtvnw.net/previews-ttv/live_user_hackerc0w-640x360.jpg","template":"http://static-cdn.jtvnw.net/previews-ttv/live_user_hackerc0w-{width}x{height}.jpg"},"channel":{"_links":{"self":"https://api.twitch.tv/kraken/channels/hackerc0w","follows":"https://api.twitch.tv/kraken/channels/hackerc0w/follows","commercial":"https://api.twitch.tv/kraken/channels/hackerc0w/commercial","stream_key":"https://api.twitch.tv/kraken/channels/hackerc0w/stream_key","chat":"https://api.twitch.tv/kraken/chat/hackerc0w","features":"https://api.twitch.tv/kraken/channels/hackerc0w/features","subscriptions":"https://api.twitch.tv/kraken/channels/hackerc0w/subscriptions","editors":"https://api.twitch.tv/kraken/channels/hackerc0w/editors","videos":"https://api.twitch.tv/kraken/channels/hackerc0w/videos","teams":"https://api.twitch.tv/kraken/channels/hackerc0w/teams"},"background":null,"banner":null,"broadcaster_language":"en","display_name":"hackerc0w","game":"Programming","logo":null,"mature":false,"status":"Coding a Chatbot in C","partner":false,"url":"http://www.twitch.tv/hackerc0w","video_banner":null,"_id":41236491,"name":"hackerc0w","created_at":"2013-03-11T17:08:22Z","updated_at":"2015-04-01T17:17:44Z","delay":0,"followers":28,"profile_banner":null,"profile_banner_background_color":null,"views":2948,"language":"de"}}}

The way I got if the livestreamer was live was like this:

public static boolean isStreamLive(String channel) { try { URL url = new URL(TWITCH_STREAM.replace("$c$", channel)) ); URLConnection conn = url.openConnection(); BufferedReader br = new BufferedReader( new InputStreamReader( conn.getInputStream() )); String inputLine = br.readLine(); br.close(); JsonObject jsonObj = JsonObject.readFrom(inputLine); return ( jsonObj.get("stream").isNull() )?false:true; } catch (IOException e) { return false; } }

And I mostly tried to copy the method above. But I have been checking the documentation of the library to know and I have been trying a lot of things.
The last was this:

public static String checkGame(String channel) { if (!isStreamLive(channel)) return "El Estreamer esta Offline!"; try { URL url = new URL( insertChannel(TWITCH_STREAM, channel) ); URLConnection conn = url.openConnection(); BufferedReader br = new BufferedReader( new InputStreamReader( conn.getInputStream() )); String inputLine = br.readLine(); br.close(); JsonObject object = JsonObject.readFrom(inputLine); JsonValue value = object.get("stream").asObject(); String msg = value.valueOf("status").toString(); return msg; } catch (IOException e) { return "Algo raro paso :/ error: 3"; } return channel; }


Solution

  • You've got two main problems with the code you've shown.

    The first problem that you're having is that you're trying to get the status out of the wrong nested object. You're getting the stream object from the original json and then trying to get the value of the status key from that, but in the json you've posted status is part of a nested channel object.

    The structure of the json object is like so:

    {
        "_links": { ... },
        "stream": {
            ...
            "channel":{
                "_links": { ...  },
                ...
                "status":"Coding a Chatbot in C",
                ...
            }
        }
    }
    

    ... so you can't get status directly from stream, you need to get channel from stream and get the status from that.


    The second problem is that you're trying to use valueOf() to pull a value out of a JsonObject. valueOf() is a static method which creates a new object based on the supplied input, so it doesn't actually use data in the object you call it on.

    Calling value.valueOf("status") will completely ignore data in value and create a new JsonObject containing the string "status".

    If you want to get the value of a nested object, you need to drill down to it with a series of successive get("objName").asObject() calls, and then call .get("key") to obtain the value you want:

        // hardcoded for example, actually would be read from BufferedReader
        String inputLine = "{\"_links\":{\"self\":\"https://api.twitch.tv/kraken/streams/hackerc0w\",\"channel\":\"https://api.twitch.tv/kraken/channels/hackerc0w\"},\"stream\":{\"_id\":13817896816,\"game\":\"Programming\",\"viewers\":13,\"created_at\":\"2015-04-01T13:54:54Z\",\"video_height\":1080,\"average_fps\":59.9235368156,\"_links\":{\"self\":\"https://api.twitch.tv/kraken/streams/hackerc0w\"},\"preview\":{\"small\":\"http://static-cdn.jtvnw.net/previews-ttv/live_user_hackerc0w-80x45.jpg\",\"medium\":\"http://static-cdn.jtvnw.net/previews-ttv/live_user_hackerc0w-320x180.jpg\",\"large\":\"http://static-cdn.jtvnw.net/previews-ttv/live_user_hackerc0w-640x360.jpg\",\"template\":\"http://static-cdn.jtvnw.net/previews-ttv/live_user_hackerc0w-{width}x{height}.jpg\"},\"channel\":{\"_links\":{\"self\":\"https://api.twitch.tv/kraken/channels/hackerc0w\",\"follows\":\"https://api.twitch.tv/kraken/channels/hackerc0w/follows\",\"commercial\":\"https://api.twitch.tv/kraken/channels/hackerc0w/commercial\",\"stream_key\":\"https://api.twitch.tv/kraken/channels/hackerc0w/stream_key\",\"chat\":\"https://api.twitch.tv/kraken/chat/hackerc0w\",\"features\":\"https://api.twitch.tv/kraken/channels/hackerc0w/features\",\"subscriptions\":\"https://api.twitch.tv/kraken/channels/hackerc0w/subscriptions\",\"editors\":\"https://api.twitch.tv/kraken/channels/hackerc0w/editors\",\"videos\":\"https://api.twitch.tv/kraken/channels/hackerc0w/videos\",\"teams\":\"https://api.twitch.tv/kraken/channels/hackerc0w/teams\"},\"background\":null,\"banner\":null,\"broadcaster_language\":\"en\",\"display_name\":\"hackerc0w\",\"game\":\"Programming\",\"logo\":null,\"mature\":false,\"status\":\"Coding a Chatbot in C\",\"partner\":false,\"url\":\"http://www.twitch.tv/hackerc0w\",\"video_banner\":null,\"_id\":41236491,\"name\":\"hackerc0w\",\"created_at\":\"2013-03-11T17:08:22Z\",\"updated_at\":\"2015-04-01T17:17:44Z\",\"delay\":0,\"followers\":28,\"profile_banner\":null,\"profile_banner_background_color\":null,\"views\":2948,\"language\":\"de\"}}}";
    
        JsonObject object = JsonObject.readFrom(inputLine);    // parse json into object
        JsonObject stream = object.get("stream").asObject();   // get "stream" sub-object
        JsonObject channel = stream.get("channel").asObject(); // get "channel" sub-object
        JsonValue status = channel.get("status");              // get the value of "status"
        String msg = status.asString();
        System.out.println(msg);  // Coding a Chatbot in C