2021SC@SDUSC
public static String toJSONString(Object object, //
SerializeConfig config, //
SerializeFilter[] filters, //
String dateFormat, //
int defaultFeatures, //
SerializerFeature... features) {
SerializeWriter out = new SerializeWriter(null, defaultFeatures, features);
try {
JSONSerializer serializer = new JSONSerializer(out, config);
if (dateFormat != null && dateFormat.length() != 0) {
serializer.setDateFormat(dateFormat);
serializer.config(SerializerFeature.WriteDateUseDateFormat, true);
}
if (filters != null) {
for (SerializeFilter filter : filters) {
serializer.addFilter(filter);
}
}
serializer.write(object);
return out.toString();
} finally {
out.close();
}
}
来看Serializer的write方法:
public final void write(Object object) {
if (object == null) {
out.writeNull();
return;
}
Class<?> clazz = object.getClass();
ObjectSerializer writer = getObjectWriter(clazz);
try {
writer.write(this, object, null, null, 0);
} catch (IOException e) {
throw new JSONException(e.getMessage(), e);
}
}
首先进行了对对象的判空操作
然后获取了对象的类型
然后获取了该类对应的(ObjectSerializer)write方法,这里的getObjectWriter是一个工厂方法,通过这种模式返回对象,里面包含了构造方法的执行,内部的实现类似于HashMap中的get方法,而这个class和writer的映射关系存储在identityHashMap中,这个映射关系在SerializeConfig初始化的时候就已经确定了。
然后接下来执行(ObjectSerializer)write的write方法:
public interface ObjectSerializer {
void write(JSONSerializer serializer, //
Object object, //
Object fieldName, //
Type fieldType, //
int features) throws IOException;
}
直接点开这个write方法我们发现它是一个interface,而在serializer这个包里面有很多的类都实现了这个接口,那么我们以一个具体的类来说明,这里以serializer包中的实现了ObjectSerializer为例:
假设我们的java bean是这样定义的:
public class User {
private String userName;
private String age;
public User(String userName,String age){
this.userName = userName;
this.age = age;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}
那么在JSON类中,JSONSerilizer对象在调用write方法以后,进行到利用工厂模式获得(ObjectSerializer)write中,这里调用了SerializerConfig的createJavaBeanSerializer方法(如下):
public final ObjectSerializer createJavaBeanSerializer(Class<?> clazz) {
String className = clazz.getName();
long hashCode64 = TypeUtils.fnv1a_64(className);
if (Arrays.binarySearch(denyClasses, hashCode64) >= 0) {
throw new JSONException("not support class : " + className);
}
SerializeBeanInfo beanInfo = TypeUtils.buildBeanInfo(clazz, null, propertyNamingStrategy, fieldBased);
if (beanInfo.fields.length == 0 && Iterable.class.isAssignableFrom(clazz)) {
return MiscCodec.instance;
}
return createJavaBeanSerializer(beanInfo);
}
抛开异常的部分不看,上面使用了TypeUtils.buildBeanInfo方法,该方法里调用了如下方法:
public static void parserAllFieldToCache(Class<?> clazz,Map</**fieldName*/String , Field> fieldCacheMap){
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
String fieldName = field.getName();
if (!fieldCacheMap.containsKey(fieldName)) {
fieldCacheMap.put(fieldName, field);
}
}
if (clazz.getSuperclass() != null && clazz.getSuperclass() != Object.class) {
parserAllFieldToCache(clazz.getSuperclass(), fieldCacheMap);
}
}
即通过反射获取该类的所有字段。在这一步,还要用get方法获得成员变量,
然后再根据json格式生成字符:
protected char[] genFieldNameChars() {
int nameLen = this.name.length();
char[] name_chars = new char[nameLen + 3];
this.name.getChars(0, this.name.length(), name_chars, 1);
name_chars[0] = '"';
name_chars[nameLen + 1] = '"';
name_chars[nameLen + 2] = ':';
return name_chars;
}
当一个对象的字段全部write之后,再进行下一个字段。