简体   繁体   中英

Creating hashmap from json data

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.

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 !

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM