Home | FAQ | Contact me

JSON Strings

Here's an example of using Fang Yidong's json-simple utility. This is is more or less a simple decorator around a specific decoding aspect. For his utility, see http://code.google.com/p/json-simple/.

This class is very naïve (probably why it wasn't provided by json-simple in the first place): it won't do JSONs with any hierarchical depth, but that's never what I'm looking for. I wrote it to parse the very simple JSON output from a service in REST-assured enhanced tests of my service.

For extra credit, this utility will also manage additions to the map, erasure of tuples and replacement of values therefrom.

Prerequisites

Beyond typical Java 5 libraries only json-simple-1.1.jar (or later) is needed.

package com.hp.web.user.util;

import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.json.simple.parser.ContainerFactory;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

/**
 * This is more or less a decorator around a specific decoding aspect of
 * FangYidong's json-simple. See http://code.google.com/p/json-simple/.
 *
 * It won't do JSONs with hierarchical depth, but only very simple JSON output.
 *
 * For extra credit, this utility will also manage additions to the map, erasure
 * of tuples and replacement of values therefrom.
 *
 * Prerequisites
 *
 * Beyond typical Java 5 libraries only json-simple-1.1.jar (or later) is
 * needed.
 *
 * @author Russell Bateman
 */
public class SimpleJsonStringDecoder
{
    public static Logger log = Logger.getLogger( SimpleJsonStringDecoder.class );

    private Map< String, String > jsonMap;

    /**
     * Construct a map of key-value tuples from the input string.
     *
     * @param jsonString properly formed JSON as a string.
     */
    @SuppressWarnings( "unchecked" )
    public SimpleJsonStringDecoder( String jsonString )
    {
        JSONParser       parser  = new JSONParser();
        ContainerFactory factory = new ContainerFactory()
        {
            public List< String > creatArrayContainer()
            {
                return new LinkedList< String >();
            }

            public Map< String, String >  createObjectContainer()
            {
                return new LinkedHashMap< String, String >();
            }
        };

        try
        {
            this.jsonMap = ( Map< String, String > ) parser.parse( jsonString, factory );
        }
        catch( ParseException e )
        {
            e.printStackTrace();
        }
    }

    /**
     * Fetch value associated with specified key.
     *
     * @param keyToFind the key to find.
     * @return value associated with that key if found else null.
     */
    public final String get( String keyToFind )
    {
        Iterator< Map.Entry< String, String > > iter = jsonMap.entrySet().iterator();

        while( iter.hasNext() )
        {
            Map.Entry< String, String > entry = ( Map.Entry< String, String > ) iter.next();
            String                      key   = entry.getKey();

            if( !key.equals( keyToFind ) )
                continue;

            return entry.getValue();
        }

        return null;
    }

    /**
     * Add key-value pair to the JSON map.
     *
     * @param keyToFind the new key.
     * @param valueToAdd the value to associate with the new key.
     * @return true or false that the key wasn't already found and that the operation was successful.
     */
    public final boolean put( String keyToAdd, String valueToAdd )
    {
        Iterator< Map.Entry< String, String > > iter = jsonMap.entrySet().iterator();

        while( iter.hasNext() )
        {
            Map.Entry< String, String > entry = ( Map.Entry< String, String > ) iter.next();
            String                      key   = entry.getKey();

            if( key.equals( keyToAdd ) )
                return false;
        }

        jsonMap.put( keyToAdd, valueToAdd );
        return true;
    }

    /**
     * Determine if specified key is found in the JSON.
     *
     * @param keyToFind the key to find.
     * @return true or false that the key exists.
     */
    public final boolean keyInJson( String keyToFind )
    {
        Iterator< Map.Entry< String, String > > iter = jsonMap.entrySet().iterator();

        while( iter.hasNext() )
        {
            Map.Entry< String, String > entry = ( Map.Entry< String, String > ) iter.next();
            String                      key   = entry.getKey();

            if( !key.equals( keyToFind ) )
                continue;

            return true;
        }

        return false;
    }

    /**
     * Replace value associated with specified key in the JSON.
     *
     * @param keyToFind the key to find.
     * @param valueToReplace the value to associate with the key.
     * @return true or false that the key was found and that the operation was successful.
     */
    public final boolean replace( String keyToFind, String valueToReplace )
    {
        Iterator< Map.Entry< String, String > > iter = jsonMap.entrySet().iterator();

        while( iter.hasNext() )
        {
            Map.Entry< String, String > entry = ( Map.Entry< String, String > ) iter.next();
            String                      key   = entry.getKey();

            if( key.equals( keyToFind ) )
            {
                entry.setValue( valueToReplace );
                return true;
            }
        }

        return false;
    }

    /**
     * Replace value associated with specified key in the JSON.
     *
     * @param keyToRemove the key to remove.
     * @return true or false that the key was found and that the tuple was removed from the map.
     */
    public final boolean remove( String keyToRemove )
    {
        Iterator< Map.Entry< String, String > > iter = jsonMap.entrySet().iterator();

        while( iter.hasNext() )
        {
            Map.Entry< String, String > entry = ( Map.Entry< String, String > ) iter.next();
            String                      key   = entry.getKey();

            if( key.equals( keyToRemove ) )
            {
                iter.remove();
                return true;
            }
        }

        return false;
    }

    /**
     * Return the (potentially modified) JSON string. If neither the remove() nor
     * the replace() method was called, this is a waste of computation as the string
     * passed originally to the constructor is what will come out.
     */
    public final String toString()
    {
        StringBuffer                            buffer = new StringBuffer();
        Iterator< Map.Entry< String, String > > iter   = jsonMap.entrySet().iterator();

        buffer.append( "{ " );

        while( iter.hasNext() )
        {
            Map.Entry< String, String > entry = ( Map.Entry< String, String > ) iter.next();
            String                      key   = entry.getKey();
            String                      value = entry.getValue();

            buffer.append( "\"" + key + "\":\"" + value + "\"," );
        }

        buffer.append( " }" );

        return buffer.toString();
    }
}