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.
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();
}
}