📄 json.java
字号:
//========================================================================//Copyright 2004-2008 Mort Bay Consulting Pty. Ltd.//------------------------------------------------------------------------//Licensed under the Apache License, Version 2.0 (the "License");//you may not use this file except in compliance with the License.//You may obtain a copy of the License at //http://www.apache.org/licenses/LICENSE-2.0//Unless required by applicable law or agreed to in writing, software//distributed under the License is distributed on an "AS IS" BASIS,//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.//See the License for the specific language governing permissions and//limitations under the License.//========================================================================package org.mortbay.util.ajax;import java.io.Externalizable;import java.io.IOException;import java.io.InputStream;import java.io.Reader;import java.lang.reflect.Array;import java.lang.reflect.Constructor;import java.util.ArrayList;import java.util.Collection;import java.util.HashMap;import java.util.Iterator;import java.util.Map;import org.mortbay.log.Log;import org.mortbay.util.IO;import org.mortbay.util.Loader;import org.mortbay.util.QuotedStringTokenizer;import org.mortbay.util.TypeUtil;/** JSON Parser and Generator. * * <p>This class provides some static methods to convert POJOs to and from JSON * notation. The mapping from JSON to java is:<pre> * object ==> Map * array ==> Object[] * number ==> Double or Long * string ==> String * null ==> null * bool ==> Boolean * </pre> * </p><p> * The java to JSON mapping is:<pre> * String --> string * Number --> number * Map --> object * List --> array * Array --> array * null --> null * Boolean--> boolean * Object --> string (dubious!) * </pre> * </p><p> * The interface {@link JSON.Convertible} may be implemented by classes that wish to externalize and * initialize specific fields to and from JSON objects. Only directed acyclic graphs of objects are supported. * </p> * <p> * The interface {@link JSON.Generator} may be implemented by classes that know how to render themselves as JSON and * the {@link #toString(Object)} method will use {@link JSON.Generator#addJSON(StringBuffer)} to generate the JSON. * The class {@link JSON.Literal} may be used to hold pre-gnerated JSON object. * <p> * The interface {@link Convertor} may be implemented to provide static convertors for objects that may be registered * with {@link #registerConvertor(Class, org.mortbay.util.ajax.JSON.Convertor)}. These convertors are looked up by class, interface and * super class by {@link #getConvertor(Class)}. * </p> * @author gregw * */public class JSON{ private static JSON __default = new JSON(); private Map _convertors=new HashMap(); private int _stringBufferSize=256; public JSON() { } /* ------------------------------------------------------------ */ /** * @return the initial stringBuffer size to use when creating JSON strings (default 256) */ public int getStringBufferSize() { return _stringBufferSize; } /* ------------------------------------------------------------ */ /** * @param stringBufferSize the initial stringBuffer size to use when creating JSON strings (default 256) */ public void setStringBufferSize(int stringBufferSize) { _stringBufferSize=stringBufferSize; } /** * Register a {@link Convertor} for a class or interface. * @param forClass The class or interface that the convertor applies to * @param convertor the convertor */ public static void registerConvertor(Class forClass, Convertor convertor) { __default.addConvertor(forClass,convertor); } public static JSON getDefault() { return __default; } public static void setDefault(JSON json) { __default=json; } public static String toString(Object object) { StringBuffer buffer=new StringBuffer(__default.getStringBufferSize()); synchronized (buffer) { __default.append(buffer,object); return buffer.toString(); } } public static String toString(Map object) { StringBuffer buffer=new StringBuffer(__default.getStringBufferSize()); synchronized (buffer) { __default.appendMap(buffer,object); return buffer.toString(); } } public static String toString(Object[] array) { StringBuffer buffer=new StringBuffer(__default.getStringBufferSize()); synchronized (buffer) { __default.appendArray(buffer,array); return buffer.toString(); } } /** * @param s String containing JSON object or array. * @return A Map, Object array or primitive array parsed from the JSON. */ public static Object parse(String s) { return __default.parse(new StringSource(s),false); } /** * @param s String containing JSON object or array. * @param stripOuterComment If true, an outer comment around the JSON is ignored. * @return A Map, Object array or primitive array parsed from the JSON. */ public static Object parse(String s, boolean stripOuterComment) { return __default.parse(new StringSource(s),stripOuterComment); } /** * @param in Reader containing JSON object or array. * @return A Map, Object array or primitive array parsed from the JSON. */ public static Object parse(Reader in) throws IOException { return __default.parse(new ReaderSource(in),false); } /** * @param s Stream containing JSON object or array. * @param stripOuterComment If true, an outer comment around the JSON is ignored. * @return A Map, Object array or primitive array parsed from the JSON. */ public static Object parse(Reader in, boolean stripOuterComment) throws IOException { return __default.parse(new ReaderSource(in),stripOuterComment); } /** * @deprecated use {@link #parse(Reader)} * @param in Reader containing JSON object or array. * @return A Map, Object array or primitive array parsed from the JSON. */ public static Object parse(InputStream in) throws IOException { return __default.parse(new StringSource(IO.toString(in)),false); } /** * @deprecated use {@link #parse(Reader, boolean)} * @param s Stream containing JSON object or array. * @param stripOuterComment If true, an outer comment around the JSON is ignored. * @return A Map, Object array or primitive array parsed from the JSON. */ public static Object parse(InputStream in, boolean stripOuterComment) throws IOException { return __default.parse(new StringSource(IO.toString(in)),stripOuterComment); } /* ------------------------------------------------------------ */ /** Convert Object to JSON * @param object The object to convert * @return The JSON String */ public String toJSON(Object object) { StringBuffer buffer=new StringBuffer(getStringBufferSize()); synchronized (buffer) { append(buffer,object); return buffer.toString(); } } /* ------------------------------------------------------------ */ /** Convert JSON to Object * @param json The json to convert * @return The object */ public Object fromJSON(String json) { Source source = new StringSource(json); return parse(source); } /** * Append object as JSON to string buffer. * @param buffer * @param object */ public void append(StringBuffer buffer, Object object) { if (object==null) buffer.append("null"); else if (object instanceof Convertible) appendJSON(buffer,(Convertible)object); else if (object instanceof Generator) appendJSON(buffer,(Generator)object); else if (object instanceof Map) appendMap(buffer,(Map)object); else if (object instanceof Collection) appendArray(buffer,(Collection)object); else if (object.getClass().isArray()) appendArray(buffer,object); else if (object instanceof Number) appendNumber(buffer,(Number)object); else if (object instanceof Boolean) appendBoolean(buffer,(Boolean)object); else if (object instanceof String) appendString(buffer,(String)object); else { Convertor convertor=getConvertor(object.getClass()); if (convertor!=null) appendJSON(buffer,convertor,object); else appendString(buffer,object.toString()); } } public void appendNull(StringBuffer buffer) { buffer.append("null"); } public void appendJSON(final StringBuffer buffer, final Convertor convertor, final Object object) { appendJSON(buffer,new Convertible() { public void fromJSON(Map object) { } public void toJSON(Output out) { convertor.toJSON(object,out); } }); } public void appendJSON(final StringBuffer buffer, Convertible converter) { final char[] c= { '{' }; converter.toJSON(new Output() { public void add(Object obj) { if (c[0]==0) throw new IllegalStateException(); append(buffer,obj); c[0]=0; } public void addClass(Class type) { if (c[0]==0) throw new IllegalStateException(); buffer.append(c); buffer.append("\"class\":"); append(buffer,type.getName()); c[0]=','; } public void add(String name, Object value) { if (c[0]==0) throw new IllegalStateException(); buffer.append(c); QuotedStringTokenizer.quote(buffer,name); buffer.append(':'); append(buffer,value); c[0]=','; } public void add(String name, double value) { if (c[0]==0) throw new IllegalStateException(); buffer.append(c); QuotedStringTokenizer.quote(buffer,name); buffer.append(':'); appendNumber(buffer,new Double(value)); c[0]=','; } public void add(String name, long value) { if (c[0]==0) throw new IllegalStateException(); buffer.append(c); QuotedStringTokenizer.quote(buffer,name); buffer.append(':'); appendNumber(buffer,TypeUtil.newLong(value)); c[0]=','; } public void add(String name, boolean value) { if (c[0]==0) throw new IllegalStateException(); buffer.append(c); QuotedStringTokenizer.quote(buffer,name); buffer.append(':'); appendBoolean(buffer,value?Boolean.TRUE:Boolean.FALSE); c[0]=','; } }); if (c[0]=='{') buffer.append("{}"); else if (c[0]!=0) buffer.append("}"); } public void appendJSON(StringBuffer buffer, Generator generator) { generator.addJSON(buffer); } public void appendMap(StringBuffer buffer, Map object) { if (object==null) { appendNull(buffer); return; } buffer.append('{'); Iterator iter=object.entrySet().iterator(); while (iter.hasNext()) { Map.Entry entry=(Map.Entry)iter.next(); QuotedStringTokenizer.quote(buffer,entry.getKey().toString()); buffer.append(':'); append(buffer,entry.getValue()); if (iter.hasNext()) buffer.append(','); } buffer.append('}'); } public void appendArray(StringBuffer buffer, Collection collection) { if (collection==null) { appendNull(buffer); return; } buffer.append('['); Iterator iter=collection.iterator(); boolean first=true; while (iter.hasNext()) { if (!first) buffer.append(','); first=false; append(buffer,iter.next()); } buffer.append(']'); } public void appendArray(StringBuffer buffer, Object array) { if (array==null) { appendNull(buffer); return; } buffer.append('['); int length=Array.getLength(array); for (int i=0; i<length; i++) { if (i!=0) buffer.append(','); append(buffer,Array.get(array,i)); } buffer.append(']'); } public void appendBoolean(StringBuffer buffer, Boolean b) { if (b==null) { appendNull(buffer); return; } buffer.append(b.booleanValue()?"true":"false"); } public void appendNumber(StringBuffer buffer, Number number) { if (number==null) { appendNull(buffer); return; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -