以前的fastjson我不清楚..
而且这个问题网上好像没什么答案...
so...
看了下源码,不得不说阿里大佬写的代码是真的给力啊...
解决方案主要有两种...
方案1:定义一个类继承TypeReference
T为LinkedHashMap
例如:
import java.util.LinkedHashMap;
import com.alibaba.fastjson.TypeReference;
public class LinkedTypeReference extends TypeReference> {
}
调用时使用:
JSONObject.parseObject(jsonString,new LinkedTypeReference());
方案2:两种方式均可
columnJson = JSONObject.parseObject(jsonString,new LinkedHashMap().getClass());
columnJson = JSONObject.parseObject(jsonString,LinkedHashMap.class);
接下来有兴趣的小伙伴可以来瞄一眼源码,看看这两种方式是否真的能见效呢...
直接以方案2为例,其实都是走的一样的接口..
核心类JSON.java
@SuppressWarnings("unchecked")
public static final T parseObject(String text, Class clazz, Feature... features) {
return (T) parseObject(text, (Type) clazz, ParserConfig.getGlobalInstance(), DEFAULT_PARSER_FEATURE, features);
}
这里可以看出,把class转成type了,构造函数就不进一步跟踪了,都是一个妈出来的,继续往里面看
@SuppressWarnings("unchecked")
public static final 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 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
那么很简单了..我们只需要看看他默认添加了哪些类型的对象就可以了,那么这些类型也就是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
this.map = map;
}
public JSONObject(boolean ordered){
this(DEFAULT_INITIAL_CAPACITY, ordered);
}
public JSONObject(int initialCapacity, boolean ordered){
if (ordered) {
map = new LinkedHashMap
} else {
map = new HashMap
}
}