以前的fastjson我不清楚..
而且这个问题网上好像没什么答案...
so...
看了下源码,给各位提供个@R_301_463@案..
@R_301_463@案主要有两种...
方案1:定义一个类继承TypeReference<T>
T为LinkedHashMap<String,Object>
例如:
import java.util.LinkedHashMap; import com.alibaba.fastjson.TypeReference; public class LinkedTypeReference extends TypeReference<LinkedHashMap<String,Object>> { }调用时使用:
JSONObject.parSEObject(jsonString,new LinkedTypeReference());
方案2:两种方式均可
columnJson = JSONObject.parSEObject(jsonString,new LinkedHashMap<String,Object>().getClass()); columnJson = JSONObject.parSEObject(jsonString,LinkedHashMap.class);
接下来有兴趣的小伙伴可以来瞄一眼源码,看看这两种方式是否真的能见效呢...
直接以方案2为例,其实都是走的一样的接口..
核心类JSON.java
@SuppressWarnings("unchecked") public static final <T> T parSEObject(String text,Class<T> clazz,Feature... features) { return (T) parSEObject(text,(Type) clazz,ParserConfig.getGlobalInstance(),DEFAULT_PARSER_FEATURE,features); }这里可以看出,把class转成type了,构造函数就不进一步跟踪了,都是一个妈出来的,继续往里面看
@SuppressWarnings("unchecked") public static final <T> T parSEObject(String input,Type clazz,ParserConfig config,ParseProcess processor,int featureValues,Feature... features) { if (input == null) { return null; } for (Feature featrue : features) { featureValues = Feature.config(featureValues,featrue,true); } DefaultJSONParser parser = new DefaultJSONParser(input,config,featureValues); if (processor instanceof ExtraTypeProvider) { parser.getExtraTypeProviders().add((ExtraTypeProvider) processor); } if (processor instanceof ExtraProcessor) { parser.getExtraProcessors().add((ExtraProcessor) processor); } T value = (T) parser.parSEObject(clazz);//执行解析对象,以及解析为什么对象,就是刚刚传过来的那个class了.. parser.handleResovleTask(value); parser.close(); return (T) value; }我们看到T value = (T) parser.parSEObject(clazz);了,现在是不是得要再深入一点...不然不满足啊...
@SuppressWarnings("unchecked") public <T> T parSEObject(Type type) { if (lexer.token() == JSONToken.NULL) { lexer.nextToken(); return null; } if (lexer.token() == JSONToken.LITERAL_STRING) { type = TypeUtils.unwrap(type); if (type == byte[].class) { byte[] bytes = lexer.bytesValue(); lexer.nextToken(); return (T) bytes; } if (type == char[].class) { String strVal = lexer.stringVal(); lexer.nextToken(); return (T) strVal.tocharArray(); } } ObjectDeserializer derializer = config.getDeserializer(type);//获取序列化方式 try { return (T) derializer.deserialze(this,type,null); } catch (JSONException e) { throw e; } catch (Throwable e) { throw new JSONException(e.getMessage(),e); } }ObjectDeserializer derializer = config.getDeserializer(type);通过对应的type获取对应的序列化方式
public ObjectDeserializer getDeserializer(Type type) { ObjectDeserializer derializer = this.derializers.get(type); if (derializer != null) { return derializer; } if (type instanceof Class<?>) { return getDeserializer((Class<?>) type,type); } if (type instanceof ParameterizedType) { Type rawType = ((ParameterizedType) type).getRawType(); if (rawType instanceof Class<?>) { return getDeserializer((Class<?>) rawType,type); } else { return getDeserializer(rawType); } } return JavaObjectDeserializer.instance; }此处ObjectDeserializer derializer = this.derializers.get(type);获取
this.derializers也是一个map
private final IdentityHashMap<Type,ObjectDeserializer> derializers = new IdentityHashMap<Type,ObjectDeserializer>();
那么很简单了..我们只需要看看他默认添加了哪些类型的对象就可以了,那么这些类型也就是fastjson所支持的类型了...
接下来好像有那么点点....长....
但是好像发现了linkedHashMap的呻吟了啊...哦..是身影
private ParserConfig(ASMDeserializerFactory asmFactory,ClassLoader parentClassLoader){ if (asmFactory == null) { try { if (parentClassLoader == null) { asmFactory = ASMDeserializerFactory.getInstance(); } else { asmFactory = new ASMDeserializerFactory(parentClassLoader); } } catch (ExceptionInInitializerError error) { // skip } catch (AccessControlException error) { // skip } catch (NoClassDefFoundError error) { // skip } } this.asmFactory = asmFactory; if (asmFactory == null) { asmEnable = false; } primitiveClasses.add(boolean.class); primitiveClasses.add(Boolean.class); primitiveClasses.add(char.class); primitiveClasses.add(Character.class); primitiveClasses.add(byte.class); primitiveClasses.add(Byte.class); primitiveClasses.add(short.class); primitiveClasses.add(Short.class); primitiveClasses.add(int.class); primitiveClasses.add(Integer.class); primitiveClasses.add(long.class); primitiveClasses.add(Long.class); primitiveClasses.add(float.class); primitiveClasses.add(Float.class); primitiveClasses.add(double.class); primitiveClasses.add(Double.class); primitiveClasses.add(BigInteger.class); primitiveClasses.add(BigDecimal.class); primitiveClasses.add(String.class); primitiveClasses.add(java.util.Date.class); primitiveClasses.add(java.sql.Date.class); primitiveClasses.add(java.sql.Time.class); primitiveClasses.add(java.sql.Timestamp.class); derializers.put(SimpleDateFormat.class,DateFormatDeserializer.instance); derializers.put(java.sql.Timestamp.class,TimestampDeserializer.instance); derializers.put(java.sql.Date.class,sqlDateDeserializer.instance); derializers.put(java.sql.Time.class,TimeDeserializer.instance); derializers.put(java.util.Date.class,DateDeserializer.instance); derializers.put(Calendar.class,CalendarCodec.instance); derializers.put(JSONObject.class,JSONObjectDeserializer.instance); derializers.put(JSONArray.class,JSONArrayDeserializer.instance); derializers.put(Map.class,MapDeserializer.instance); derializers.put(HashMap.class,MapDeserializer.instance); derializers.put(LinkedHashMap.class,MapDeserializer.instance); derializers.put(TreeMap.class,MapDeserializer.instance); derializers.put(ConcurrentMap.class,MapDeserializer.instance); derializers.put(ConcurrentHashMap.class,MapDeserializer.instance); derializers.put(Collection.class,CollectionDeserializer.instance); derializers.put(List.class,CollectionDeserializer.instance); derializers.put(ArrayList.class,CollectionDeserializer.instance); derializers.put(Object.class,JavaObjectDeserializer.instance); derializers.put(String.class,StringCodec.instance); derializers.put(char.class,CharacterCodec.instance); derializers.put(Character.class,CharacterCodec.instance); derializers.put(byte.class,NumberDeserializer.instance); derializers.put(Byte.class,NumberDeserializer.instance); derializers.put(short.class,NumberDeserializer.instance); derializers.put(Short.class,NumberDeserializer.instance); derializers.put(int.class,IntegerCodec.instance); derializers.put(Integer.class,IntegerCodec.instance); derializers.put(long.class,LongCodec.instance); derializers.put(Long.class,LongCodec.instance); derializers.put(BigInteger.class,BigIntegerCodec.instance); derializers.put(BigDecimal.class,BigDecimalCodec.instance); derializers.put(float.class,FloatCodec.instance); derializers.put(Float.class,FloatCodec.instance); derializers.put(double.class,NumberDeserializer.instance); derializers.put(Double.class,NumberDeserializer.instance); derializers.put(boolean.class,BooleanCodec.instance); derializers.put(Boolean.class,BooleanCodec.instance); derializers.put(Class.class,ClassDerializer.instance); derializers.put(char[].class,CharArrayDeserializer.instance); derializers.put(AtomicBoolean.class,BooleanCodec.instance); derializers.put(AtomicInteger.class,IntegerCodec.instance); derializers.put(AtomicLong.class,LongCodec.instance); derializers.put(AtomicReference.class,ReferenceCodec.instance); derializers.put(WeakReference.class,ReferenceCodec.instance); derializers.put(SoftReference.class,ReferenceCodec.instance); derializers.put(UUID.class,UUIDCodec.instance); derializers.put(TimeZone.class,TimeZoneCodec.instance); derializers.put(Locale.class,LocaleCodec.instance); derializers.put(Currency.class,CurrencyCodec.instance); derializers.put(InetAddress.class,InetAddressCodec.instance); derializers.put(Inet4Address.class,InetAddressCodec.instance); derializers.put(Inet6Address.class,InetAddressCodec.instance); derializers.put(InetSocketAddress.class,InetSocketAddressCodec.instance); derializers.put(File.class,FileCodec.instance); derializers.put(URI.class,URICodec.instance); derializers.put(URL.class,URLCodec.instance); derializers.put(Pattern.class,PatternCodec.instance); derializers.put(Charset.class,CharsetCodec.instance); derializers.put(Number.class,NumberDeserializer.instance); derializers.put(AtomicIntegerArray.class,AtomicIntegerArrayCodec.instance); derializers.put(AtomicLongArray.class,AtomicLongArrayCodec.instance); derializers.put(StackTraceElement.class,StackTraceElementDeserializer.instance); derializers.put(Serializable.class,JavaObjectDeserializer.instance); derializers.put(Cloneable.class,JavaObjectDeserializer.instance); derializers.put(Comparable.class,JavaObjectDeserializer.instance); derializers.put(Closeable.class,JavaObjectDeserializer.instance); try { derializers.put(Class.forName("java.awt.Point"),PointCodec.instance); derializers.put(Class.forName("java.awt.Font"),FontCodec.instance); derializers.put(Class.forName("java.awt.Rectangle"),RectangleCodec.instance); derializers.put(Class.forName("java.awt.Color"),ColorCodec.instance); } catch (Throwable e) { // skip } try { derializers.put(Class.forName("java.time.LocalDateTime"),Jdk8DateCodec.instance); derializers.put(Class.forName("java.time.LocalDate"),Jdk8DateCodec.instance); derializers.put(Class.forName("java.time.LocalTime"),Jdk8DateCodec.instance); derializers.put(Class.forName("java.time.ZonedDateTime"),Jdk8DateCodec.instance); derializers.put(Class.forName("java.time.OffsetDateTime"),Jdk8DateCodec.instance); derializers.put(Class.forName("java.time.OffsetTime"),Jdk8DateCodec.instance); derializers.put(Class.forName("java.time.ZoneOffset"),Jdk8DateCodec.instance); derializers.put(Class.forName("java.time.ZoneRegion"),Jdk8DateCodec.instance); derializers.put(Class.forName("java.time.ZoneId"),Jdk8DateCodec.instance); derializers.put(Class.forName("java.time.Period"),Jdk8DateCodec.instance); derializers.put(Class.forName("java.time.Duration"),Jdk8DateCodec.instance); derializers.put(Class.forName("java.time.Instant"),Jdk8DateCodec.instance); } catch (Throwable e) { } }
另外我们看到提供了一个方法
public void putDeserializer(Type type,ObjectDeserializer deserializer) {
derializers.put(type,deserializer);
}
也就是说不支持的类型亲可以自己去参考其它的写一个...好了..不BB了...结束
另外再提一下..
fastjson有几个构造函数,可以让你添加数据时是有序的:
public JSONObject(Map<String,Object> map){
this.map = map;
}
public JSONObject(boolean ordered){
this(DEFAULT_INITIAL_CAPACITY,ordered);
}
public JSONObject(int initialCapacity,boolean ordered){ if (ordered) { map = new LinkedHashMap<String,Object>(initialCapacity); } else { map = new HashMap<String,Object>(initialCapacity); } }