0

I am working on a very simple application for a website, just a basic desktop application.

So I've figured out how to grab all of the JSON Data I need, and if possible, I am trying to avoid the use of external libraries to parse the JSON.

Here is what I am doing right now:

package me.thegreengamerhd.TTVPortable;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;

import me.thegreengamerhd.TTVPortable.Utils.Messenger;


public class Channel
{
URL url;
String data;
String[] dataArray;

String name;
boolean online;
int viewers;
int followers;

public Channel(String name)
{
    this.name = name;
}

public void update() throws IOException
{
    // grab all of the JSON data from selected channel, if channel exists
    try
    {
        url = new URL("https://api.twitch.tv/kraken/channels/" + name);
        URLConnection connection = url.openConnection();
        BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
        data = new String(in.readLine());
        in.close();
        // clean up data a little, into an array
        dataArray = data.split(",");
    }
    // channel does not exist, throw exception and close client
    catch (Exception e)
    {
        Messenger.sendErrorMessage("The channel you have specified is invalid or corrupted.", true);
        e.printStackTrace();
        return;
    }

    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < dataArray.length; i++)
    {
        sb.append(dataArray[i] + "\n");
    }

    System.out.println(sb.toString());
}
}

So here is what is printed when I enter an example channel (which grabs data correctly)

    {"updated_at":"2013-05-24T11:00:26Z"
"created_at":"2011-06-28T07:50:25Z"
"status":"HD [XBOX] Call of Duty Black Ops 2 OPEN LOBBY"
"url":"http://www.twitch.tv/zetaspartan21"
"_id":23170407
"game":"Call of Duty: Black Ops II"
"logo":"http://static-cdn.jtvnw.net/jtv_user_pictures/zetaspartan21-profile_image-121d2cb317e8a91c-300x300.jpeg"
"banner":"http://static-cdn.jtvnw.net/jtv_user_pictures/zetaspartan21-channel_header_image-7c894f59f77ae0c1-640x125.png"
"_links":{"subscriptions":"https://api.twitch.tv/kraken/channels/zetaspartan21/subscriptions"
"editors":"https://api.twitch.tv/kraken/channels/zetaspartan21/editors"
"commercial":"https://api.twitch.tv/kraken/channels/zetaspartan21/commercial"
"teams":"https://api.twitch.tv/kraken/channels/zetaspartan21/teams"
"features":"https://api.twitch.tv/kraken/channels/zetaspartan21/features"
"videos":"https://api.twitch.tv/kraken/channels/zetaspartan21/videos"
"self":"https://api.twitch.tv/kraken/channels/zetaspartan21"
"follows":"https://api.twitch.tv/kraken/channels/zetaspartan21/follows"
"chat":"https://api.twitch.tv/kraken/chat/zetaspartan21"
"stream_key":"https://api.twitch.tv/kraken/channels/zetaspartan21/stream_key"}
"name":"zetaspartan21"
"delay":0
"display_name":"ZetaSpartan21"
"video_banner":"http://static-cdn.jtvnw.net/jtv_user_pictures/zetaspartan21-channel_offline_image-b20322d22543539a-640x360.jpeg"
"background":"http://static-cdn.jtvnw.net/jtv_user_pictures/zetaspartan21-channel_background_image-587bde3d4f90b293.jpeg"
"mature":true}

Initializing User Interface - JOIN

All of this is correct. Now what I want to do, is to be able to grab, for example the 'mature' tag, and it's value. So when I grab it, it would be like as simple as:

// pseudo code
if(mature /*this is a boolean */ == true){ // do stuff}

So if you don't understand, I need to split away the quotes and semicolon between the values to retrieve a Key, Value.

3
  • You can write a basic JSON parser in about 500 lines of code. Have at it! (But others will question your sanity when there are probably a dozen good open source JSON parsers available for Java.) Commented May 25, 2013 at 3:20
  • Ah, well I wanted to use the one on json.org/java but I don't know how to add that to my eclipse libraries... Commented May 25, 2013 at 3:23
  • 1
    You could always ask that question. Commented May 25, 2013 at 3:27

2 Answers 2

1

It's doable with the following code :

public static Map<String, Object> parseJSON (String data) throws ParseException {
    if (data==null)
        return null;
    final Map<String, Object> ret = new HashMap<String, Object>();
    data = data.trim();
    if (!data.startsWith("{") || !data.endsWith("}"))
        throw new ParseException("Missing '{' or '}'.", 0);

    data = data.substring(1, data.length()-1);

    final String [] lines = data.split("[\r\n]");

    for (int i=0; i<lines.length; i++) {
        String line = lines[i];

        if (line.isEmpty())
            continue;

        line = line.trim();

        if (line.indexOf(":")<0)
            throw new ParseException("Missing ':'.", 0);

        String key = line.substring(0, line.indexOf(":"));
        String value = line.substring(line.indexOf(":")+1);

        if (key.startsWith("\"") && key.endsWith("\"") && key.length()>2)
            key = key.substring(1, key.length()-1);

        if (value.startsWith("{"))
            while (i+1<line.length() && !value.endsWith("}"))
                value = value + "\n" + lines[++i].trim();

        if (value.startsWith("\"") && value.endsWith("\"") && value.length()>2)
            value = value.substring(1, value.length()-1);

        Object mapValue = value;

        if (value.startsWith("{") && value.endsWith("}"))
            mapValue = parseJSON(value);
        else if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("false"))
            mapValue = new Boolean (value);
        else {
            try {
                mapValue = Integer.parseInt(value);
            } catch (NumberFormatException nfe) {
                try {
                    mapValue = Long.parseLong(value);
                } catch (NumberFormatException nfe2) {}
            }
        }

        ret.put(key, mapValue);
    }

    return ret;
}

You can call it like that :

try {
    Map<String, Object> ret = parseJSON(sb.toString());
    if(((Boolean)ret.get("mature")) == true){
        System.out.println("mature is true !");
    }
} catch (ParseException e) {

}

But, really, you shouldn't do this, and use an already existing JSON parser, because this code will break on any complex or invalid JSON data (like a ":" in the key), and if you want to build a true JSON parser by hand, it will take you a lot more code and debugging !

Sign up to request clarification or add additional context in comments.

Comments

0

This is a parser of an easy json string:

public static HashMap<String, String> parseEasyJson(String json) {
    final String regex = "([^{}: ]*?):(\\{.*?\\}|\".*?\"|[^:{}\" ]*)";
    json = json.replaceAll("\n", "");
    Matcher m = Pattern.compile(regex).matcher(json);
    HashMap<String, String> map = new HashMap<>();
    while (m.find())
        map.put(m.group(1), m.group(2));
    return map;
}

Live Demo

3 Comments

Thanks! Just curious, how can I grab the key when it contains quotes? Edit: I can't seem to grab any keys or values. Could you provide an example of that?
@MichaelGates try final String regex = "\"(.*?)\":(\\{.*?\\}|\".*?\"|[^:{}\" ]*)"; Demo
Thanks, but i figured it out on my own! Thanks for this, though!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.