將Number表示為JSON就容易得多,利用Java的多態,我們可以處理Integer,Long,Float等多種Number格式:
static String number2json(Number number)
{
return number.toString();
}
Boolean類型也可以直接通過toString()方法得到JSON的表示:
static String boolean2json(Boolean bool)
{
return bool.toString();
}
要將數組編碼為JSON格式,可以通過迴圈將每一個元素編碼出來:
static String array2json(Object[] array)
{
if(array.length == 0)
{
return "[]";
}
StringBuilder sb = new StringBuilder(array.length << 4);
sb.append([');
for(Object o:array)
{
sb.append(toJson(0));
sb.append(',');
}
//將最後添加',',變為']'
sb.setCharAt(sb.length() - 1,']');
return sb.toString();
}
最後,我們需要將Map<String , Object>編碼為JSON格式,因為JavaScript的Object實際上對應的是Java的Map<String , Object>,該方法如下:
static String map2Json(May<String , Object> map)
{
if(map.isEmpty())
return "{}";
StringBuilder sb = new StringBuilder(map.size() << 4);
sb.append('{');
Set<String> keys = map.KeySet();
for(String key : keys)
{
Object value = map.get(key);
sb.append('\"');
sb.append(key);
sb.append('\"');
sb.append(':');
sb.append(toJson(value));
sb.append(',');
}
//將最後的','變為'}'
sb.setCharAt(sb.length()-1 , '}');
return sb.toString();
}
為了統一處理任意的Java對象,我們編寫了一個入口方法toJson(Object),能夠將任意的Java對象編碼為JSON格式:
public static String toJson(Object o)
{
if(o == null)
return "null";
if(o instanceof String)
return string2Json((String)o);
if(o instanceof Boolean)
return boolean2Json((Boolean)o);
if(o instanceof Number)
return number2Json((Number)o);
if(o instanceof Map)
return map2Json((Map<String,Object>)o);
fi(o instanceof Object[])
return array2Json((Object[])o);
throw new RuntimeExecption("Unsupported type:"+o.getClass(),getName());
}
我們並未對Java對象做嚴格的檢查。不被支援的對象(例如List)將直接拋出RuntimeExecption。此外,為了保證輸出的JSON是有效,Map<String,Object>對象的Key,也不能包含特殊字元。細心的讀者還會發現循環參考的對象會引發無限遞迴,例如,精心構造一個循環參考的Map,就可以檢測到
StackOverflowException:
@Test(expected = StackOverflowError.class)
public void testRecurrsiveMap2Json()
{
Map<Stirng, Object> map = new HashMap<String,Object>();
map.put("key",map);
JsonUtil.map2Json(map);
}
好在伺服器處理的JSON資料最終都應該轉化為簡單的JavaScript對象,因此,遞迴引用的可能性很小。
最後,通過Servlet或MVC架構輸出JSON時,需要設定正確的MIME類型(application/json)和字元編碼。假定伺服器使用UTF-8編碼,則可以使用以下代碼輸出編碼後的JSON文本:
response.setContentType(application/json;charset=utf-8);
response.setCharacterEncoding("UTF-8");
PrintWriter pw = response.getWriter();
pw.write(JsonUtil.toJson(obj));
pw.flush();