1. 程式人生 > >記錄一次原始碼擴充套件案列——FastJson自定義反序列化ValueMutator

記錄一次原始碼擴充套件案列——FastJson自定義反序列化ValueMutator

背景:曾經遇到一個很麻煩的事情,就是一個json串中有很多佔位符,需要替換成特定文案。如果將json轉換成物件後,在一個一個屬性去轉換的話就出出現很多冗餘程式碼,不美觀也不是很實用。

而且也不能提前在json串中替換,因為替換的文案會因為某些變數發生改變。就比如國際化,在中文的時候應該是"你好",而在英文的時候要出現"Hello"。

所以我想到一個方法,為什麼不能再json反序列化的時候,把這些都做好呢?

以下的程式碼介紹的是,我自己擴充套件的一點點fastjson程式碼,增加了在反序列化的時候可以對所有的值進行修改的方案。

注意:這個方案會對fastjson反序列化的速度有一定的影響,我只是用來做配置的反序列化,完成後將反序列化的東西快取起來使用。

使用方式有兩種

一種是直接通過 @JsonDeserializer 註解的valueMutators屬性注入這種方式有個缺陷,你的修改器必須有無參建構函式的 

@JsonDeserializer(valueMutators = {CoustomizeValueMutator.class})  
@Getter  
@Setter  
public class User {

    private String name;
    ...
}  

第二種方式是通過直接建立的方式,使用反序列化工具,這種方式支援有參建構函式。

        CoustomizeValueMutator zhCoustomizeValueMutator = new CoustomizeValueMutator(zh);  
        User user = CustomizeJSON.parseObject(userStr, User.class, zhCoustomizeValueMutator);

 

下面先展示一下使用效果,測試程式碼如下:

import com.alibaba.fastjson.parser.deserializer.CustomizeJSON;
import com.raiden.model.*;
import org.junit.jupiter.api.Test;

import java.util.*;


/**
 * @建立人:Raiden
 * @Descriotion:
 * @Date:Created in 22:39 2020/1/28
 * @Modified By:
 */
public class AppTest {

    @Test
    public void testFastJosn() throws Throwable {
        String userStr = "{\n" +
                "\t\"id\":\"I18nKey:20200411001\",\n" +
                "\t\"a\":\"I18nKey:張三\",\n" +
                "\t\"student\":\"I18nKey:高三三班\",\n" +
                "\t\"contents\":[\"I18nKey:1\",\"I18nKey:2\"]\n" +
                "}";
        Map<String, String> en = new HashMap<>();
        en.put("3", "zhangsan");
        en.put("4", "20200411001");
        en.put("5", "Class three in grade three");
        en.put("1", "Hello");
        en.put("2", "Welcome home");
        Map<String, String> zh = new HashMap<>();
        zh.put("3", "張三");
        zh.put("4", "20200411001");
        zh.put("5", "高三三班");
        zh.put("1", "你好");
        zh.put("2", "歡迎回家");
        CoustomizeValueMutator zhCoustomizeValueMutator = new CoustomizeValueMutator(zh);

        User user = CustomizeJSON.parseObject(userStr, User.class, zhCoustomizeValueMutator);
        System.err.println(user);
        String string = "{\n" +
                "\t\"users\": [{\n" +
                "\t\t\"id\": \"I18nKey:4\",\n" +
                "\t\t\"a\": \"I18nKey:3\",\n" +
                "\t\t\"student\": \"I18nKey:5\",\n" +
                "\t\t\"url\": \"www.baidu.com\",\n" +
                "\t\t\"contents\": [\"I18nKey:1\", \"I18nKey:2\"]\n" +
                "\t}],\n" +
                "\t\"memberId\":\"2020\"\n" +
                "}";
        CoustomizeValueMutator enCoustomizeValueMutator = new CoustomizeValueMutator(en);
        Administration administration = CustomizeJSON.parseObject(string, Administration.class, enCoustomizeValueMutator);
        System.err.println(administration);
    }
}

執行效果:

 下面是測試模型程式碼:

import com.alibaba.fastjson.parser.deserializer.JsonDeserializer;
import com.raiden.CoustomizeValueMutator;
import lombok.Getter;
import lombok.Setter;

import java.util.List;

/**
 * @建立人:Raiden
 * @Descriotion:
 * @Date:Created in 23:56 2020/4/17
 * @Modified By:
 */
@JsonDeserializer
@Getter
@Setter
public class Administration {

    private List<User> users;
    private String memberId;

    @Override
    public String toString() {
        return "Administration{" +
                "users=" + users +
                ", memberId='" + memberId + '\'' +
                '}';
    }
}
import com.alibaba.fastjson.parser.deserializer.JsonDeserializer;
import lombok.Getter;
import lombok.Setter;

import java.util.List;

/**
 * @建立人:Raiden
 * @Descriotion:
 * @Date:Created in 15:53 2020/3/21
 * @Modified By:
 */
@JsonDeserializer
@Getter
@Setter
public class User {

    private String name;
    private String id;
    private String student;
    private List<String> contents;
    private String url;

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", id='" + id + '\'' +
                ", student='" + student + '\'' +
                ", contents='" + contents.toString() + '\'' +
                ", url='" + url + '\'' +
                '}';
    }
}

自定義的反序列化值修改器:

import com.alibaba.fastjson.parser.deserializer.DeserializerValueMutator;

import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @建立人:Raiden
 * @Descriotion:
 * @Date:Created in 22:15 2020/5/1
 * @Modified By:
 */
public class CoustomizeValueMutator implements DeserializerValueMutator {

    private Map<String, String> dataSource;

    public CoustomizeValueMutator(Map<String, String> dataSource){
        this.dataSource = dataSource;
    }
    @Override
    public Object process(Object object, Annotation[] annotations, String name, Object value) {
        if (value instanceof List){
            List list = new ArrayList();
            for (Object o : (List) value){
                if (!(o instanceof String)){
                    return value;
                }
                list.add(DeserializerUtils.deserializer(o, dataSource));
            }
            return list;
        }
        return DeserializerUtils.deserializer(value, dataSource);
    }
}

一些工具類和靜態資源類:

/**
 * @建立人:Raiden
 * @Descriotion:
 * @Date:Created in 23:00 2020/4/17
 * @Modified By:
 */
public class CustomizeStaticConfig {
    public static final String I18N_KEY = "I18nKey:";
}
import org.apache.commons.lang3.StringUtils;

import java.util.Map;

/**
 * @建立人:Raiden
 * @Descriotion:
 * @Date:Created in 0:15 2020/4/18
 * @Modified By:
 */
public final class DeserializerUtils {

    public static final Object deserializer(Object value, Map<String, String> languageConfig){
        String result = null;
        if (value.getClass() == String.class && StringUtils.contains((result = ((String) value).trim()), CustomizeStaticConfig.I18N_KEY)){
            int indexOf = result.indexOf(CustomizeStaticConfig.I18N_KEY) + CustomizeStaticConfig.I18N_KEY.length();
            String key = StringUtils.substring(result, indexOf);
            return languageConfig.getOrDefault(key, result);
        }
        return value;
    }
}

 下面給出的是擴充套件的關鍵程式碼。

首先是自定義解析配置類,這個類是核心。這個類繼承了 com.alibaba.fastjson.parser.ParserConfig 類。覆寫了其兩個核心方法。

方法一:

createFieldDeserializer(ParserConfig mapping, JavaBeanInfo beanInfo, FieldInfo fieldInfo) 建立一個屬性反序列化處理類

該方法的修改,是將原始碼中的 ArrayListTypeFieldDeserializer 替換成 我們自定義的 CustomizeArrayListTypeFieldDeserializer 處理器。

將原始碼中的 DefaultFieldDeserializer 替換成 我們自定義的 CustomizeDefaultFieldDeserializer 處理器

方法二:

createJavaBeanDeserializer(Class<?> clazz, Type type)  建立一個 JavaBean 反序列化處理器

新增判斷邏輯,如果要反序列化的類上存在 @JsonDeserializer 標識註解,返回包含自定義配置類的 JavaBeanDeserializer。

import com.alibaba.fastjson.annotation.JSONField;
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.util.FieldInfo;
import com.alibaba.fastjson.util.JavaBeanInfo;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
/**
 * @建立人:Raiden
 * @Descriotion:
 * @Date:Created in 21:52 2020/4/17
 * @Modified By: 自定義fastjson 解析配置類 這個類是核心
 */
public class CustomizeParserConfig extends ParserConfig {

    /**
     * 值修改器陣列 可以將類修改器放入其中使用
     */
    private DeserializerValueMutator[] valueMutators;

    public CustomizeParserConfig(){
    }

    /**
     * 有參構造方法 可以通過該方法 將類修改器放入其中
     * @param valueMutators
     */
    public CustomizeParserConfig(DeserializerValueMutator... valueMutators){
        super();
        this.valueMutators = valueMutators;
    }

    /**
     * 建立一個屬性反序列化處理類
     * @param mapping
     * @param beanInfo
     * @param fieldInfo
     * @return
     */
    @Override
    public FieldDeserializer createFieldDeserializer(ParserConfig mapping, //
                                                     JavaBeanInfo beanInfo, //
                                                     FieldInfo fieldInfo) {
        //獲取要反序列化的model 的class
        Class<?> clazz = beanInfo.clazz;
        //獲取要反序列化屬性的 class
        Class<?> fieldClass = fieldInfo.fieldClass;

        Class<?> deserializeUsing = null;
        JSONField annotation = fieldInfo.getAnnotation();
        if (annotation != null) {
            deserializeUsing = annotation.deserializeUsing();
            if (deserializeUsing == Void.class) {
                deserializeUsing = null;
            }
        }

        if (deserializeUsing == null && (fieldClass == List.class || fieldClass == ArrayList.class)) {
            //將原始碼中的 ArrayListTypeFieldDeserializer 替換成 我們自定義的 CustomizeArrayListTypeFieldDeserializer 處理器
            return new CustomizeArrayListTypeFieldDeserializer(clazz, fieldInfo, valueMutators);
        }
        //將原始碼中的 DefaultFieldDeserializer 替換成 我們自定義的 CustomizeDefaultFieldDeserializer 處理器
        return new CustomizeDefaultFieldDeserializer(mapping, clazz, fieldInfo, valueMutators);
    }

    /**
     * 建立一個 javaBean 反序列化處理器
     * @param clazz
     * @param type
     * @return
     */
    @Override
    public ObjectDeserializer createJavaBeanDeserializer(Class<?> clazz, Type type) {
        //獲取要反序列化類上的標識註解
        JsonDeserializer jsonDeserializer = clazz.getAnnotation(JsonDeserializer.class);
        //如果不存在就走原邏輯
        if (jsonDeserializer != null){
            //獲取註解中的反序列化值處理器
            Class<? extends DeserializerValueMutator>[] classes = jsonDeserializer.valueMutators();
            if (classes != null && classes.length > 0){
                DeserializerValueMutator[] mutators = new DeserializerValueMutator[classes.length];
                int size = 0;
                for (Class<? extends DeserializerValueMutator> c : classes) {
                    try {
                        DeserializerValueMutator mutator = c.newInstance();
                        mutators[size] = mutator;
                        size++;
                    } catch (Exception e) {
                        //如果建立失敗了就忽略掉這次錯誤
                    }
                }
                if (size > 0){
                    //判斷原來是否有值 如果有 就合併成一組
                    if (valueMutators != null){
                        DeserializerValueMutator[] newValueMutators = new DeserializerValueMutator[size + valueMutators.length];
                        System.arraycopy(valueMutators, 0, newValueMutators, 0, valueMutators.length);
                        System.arraycopy(mutators, 0, newValueMutators, valueMutators.length, size);
                        this.valueMutators = newValueMutators;
                    }else {
                        this.valueMutators = new DeserializerValueMutator[size];
                        System.arraycopy(mutators, 0, valueMutators, 0, size);
                    }
                }
            }
            if (valueMutators != null){
                return new JavaBeanDeserializer(this, clazz);
            }
        }
        return super.createJavaBeanDeserializer(clazz, type);
    }
}

 CustomizeDefaultFieldDeserializer 類繼承了 DefaultFieldDeserializer 類在構造方法中新增了引數 valueMutators(值修改器陣列)

並在 public void setValue(Object object, Object value) 方法中新增了邏輯如果值修改器陣列中存在值修改器,就遍歷所有的修改器,

依次呼叫修改器的 process方法修改值。

import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.util.FieldInfo;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;

/**
 * @建立人:Raiden
 * @Descriotion:
 * @Date:Created in 0:13 2020/4/18
 * @Modified By: 替代fastjson中 物件反序列化處理類
 */
public class CustomizeDefaultFieldDeserializer extends DefaultFieldDeserializer {

    private DeserializerValueMutator[] valueMutators;

    public CustomizeDefaultFieldDeserializer(ParserConfig config, Class<?> clazz, FieldInfo fieldInfo,DeserializerValueMutator[] valueMutators) {
        super(config, clazz, fieldInfo);
        this.valueMutators = valueMutators;
    }

    public void setValue(Object object, Object value) {
        if (value == null //
                && fieldInfo.fieldClass.isPrimitive()) {
            return;
        } else if (fieldInfo.fieldClass == String.class
                && fieldInfo.format != null
                && fieldInfo.format.equals("trim")){
            value = ((String) value).trim();
        }
        try {
            /**
             * 如果值修改器陣列中存在值修改器例項,就遍歷該陣列,依次呼叫所有的修改器的 process方法
             */
            if (valueMutators != null && valueMutators.length > 0){
                for (DeserializerValueMutator mutator : valueMutators){
                    value = mutator.process(object,fieldInfo.field.getAnnotations(), fieldInfo.name, value);
                }
            }
            Method method = fieldInfo.method;
            if (method != null) {
                if (fieldInfo.getOnly) {
                    if (fieldInfo.fieldClass == AtomicInteger.class) {
                        AtomicInteger atomic = (AtomicInteger) method.invoke(object);
                        if (atomic != null) {
                            atomic.set(((AtomicInteger) value).get());
                        }
                    } else if (fieldInfo.fieldClass == AtomicLong.class) {
                        AtomicLong atomic = (AtomicLong) method.invoke(object);
                        if (atomic != null) {
                            atomic.set(((AtomicLong) value).get());
                        }
                    } else if (fieldInfo.fieldClass == AtomicBoolean.class) {
                        AtomicBoolean atomic = (AtomicBoolean) method.invoke(object);
                        if (atomic != null) {
                            atomic.set(((AtomicBoolean) value).get());
                        }
                    } else if (Map.class.isAssignableFrom(method.getReturnType())) {
                        Map map = (Map) method.invoke(object);
                        if (map != null) {
                            if (map == Collections.emptyMap()
                                    || map.getClass().getName().startsWith("java.util.Collections$Unmodifiable")) {
                                // skip
                                return;
                            }

                            map.putAll((Map) value);
                        }
                    } else {
                        Collection collection = (Collection) method.invoke(object);
                        if (collection != null && value != null) {
                            if (collection == Collections.emptySet()
                                    || collection == Collections.emptyList()
                                    || collection.getClass().getName().startsWith("java.util.Collections$Unmodifiable")) {
                                // skip
                                return;
                            }

                            collection.clear();
                            collection.addAll((Collection) value);
                        }
                    }
                } else {
                    method.invoke(object, value);
                }
            } else {
                final Field field = fieldInfo.field;

                if (fieldInfo.getOnly) {
                    if (fieldInfo.fieldClass == AtomicInteger.class) {
                        AtomicInteger atomic = (AtomicInteger) field.get(object);
                        if (atomic != null) {
                            atomic.set(((AtomicInteger) value).get());
                        }
                    } else if (fieldInfo.fieldClass == AtomicLong.class) {
                        AtomicLong atomic = (AtomicLong) field.get(object);
                        if (atomic != null) {
                            atomic.set(((AtomicLong) value).get());
                        }
                    } else if (fieldInfo.fieldClass == AtomicBoolean.class) {
                        AtomicBoolean atomic = (AtomicBoolean) field.get(object);
                        if (atomic != null) {
                            atomic.set(((AtomicBoolean) value).get());
                        }
                    } else if (Map.class.isAssignableFrom(fieldInfo.fieldClass)) {
                        Map map = (Map) field.get(object);
                        if (map != null) {
                            if (map == Collections.emptyMap()
                                    || map.getClass().getName().startsWith("java.util.Collections$Unmodifiable")) {
                                // skip
                                return;
                            }
                            map.putAll((Map) value);
                        }
                    } else {
                        Collection collection = (Collection) field.get(object);
                        if (collection != null && value != null) {
                            if (collection == Collections.emptySet()
                                    || collection == Collections.emptyList()
                                    || collection.getClass().getName().startsWith("java.util.Collections$Unmodifiable")) {
                                // skip
                                return;
                            }

                            collection.clear();
                            collection.addAll((Collection) value);
                        }
                    }
                } else {
                    if (field != null) {
                        field.set(object, value);
                    }
                }
            }
        } catch (Exception e) {
            throw new JSONException("set property error, " + clazz.getName() + "#" + fieldInfo.name, e);
        }
    }
}

類CustomizeArrayListTypeFieldDeserializer 和 類CustomizeDefaultFieldDeserializer 改動類似。

import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.util.FieldInfo;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;

/**
 * @建立人:Raiden
 * @Descriotion:
 * @Date:Created in 0:13 2020/4/18
 * @Modified By: 替代fastjson中 物件反序列化處理類
 */
public class CustomizeDefaultFieldDeserializer extends DefaultFieldDeserializer {

    private DeserializerValueMutator[] valueMutators;

    public CustomizeDefaultFieldDeserializer(ParserConfig config, Class<?> clazz, FieldInfo fieldInfo,DeserializerValueMutator[] valueMutators) {
        super(config, clazz, fieldInfo);
        this.valueMutators = valueMutators;
    }

    public void setValue(Object object, Object value) {
        if (value == null //
                && fieldInfo.fieldClass.isPrimitive()) {
            return;
        } else if (fieldInfo.fieldClass == String.class
                && fieldInfo.format != null
                && fieldInfo.format.equals("trim")){
            value = ((String) value).trim();
        }
        try {
            /**
             * 如果值修改器陣列中存在值修改器例項,就遍歷該陣列,依次呼叫所有的修改器的 process方法
             */
            if (valueMutators != null && valueMutators.length > 0){
                for (DeserializerValueMutator mutator : valueMutators){
                    value = mutator.process(object,fieldInfo.field.getAnnotations(), fieldInfo.name, value);
                }
            }
            Method method = fieldInfo.method;
            if (method != null) {
                if (fieldInfo.getOnly) {
                    if (fieldInfo.fieldClass == AtomicInteger.class) {
                        AtomicInteger atomic = (AtomicInteger) method.invoke(object);
                        if (atomic != null) {
                            atomic.set(((AtomicInteger) value).get());
                        }
                    } else if (fieldInfo.fieldClass == AtomicLong.class) {
                        AtomicLong atomic = (AtomicLong) method.invoke(object);
                        if (atomic != null) {
                            atomic.set(((AtomicLong) value).get());
                        }
                    } else if (fieldInfo.fieldClass == AtomicBoolean.class) {
                        AtomicBoolean atomic = (AtomicBoolean) method.invoke(object);
                        if (atomic != null) {
                            atomic.set(((AtomicBoolean) value).get());
                        }
                    } else if (Map.class.isAssignableFrom(method.getReturnType())) {
                        Map map = (Map) method.invoke(object);
                        if (map != null) {
                            if (map == Collections.emptyMap()
                                    || map.getClass().getName().startsWith("java.util.Collections$Unmodifiable")) {
                                // skip
                                return;
                            }

                            map.putAll((Map) value);
                        }
                    } else {
                        Collection collection = (Collection) method.invoke(object);
                        if (collection != null && value != null) {
                            if (collection == Collections.emptySet()
                                    || collection == Collections.emptyList()
                                    || collection.getClass().getName().startsWith("java.util.Collections$Unmodifiable")) {
                                // skip
                                return;
                            }

                            collection.clear();
                            collection.addAll((Collection) value);
                        }
                    }
                } else {
                    method.invoke(object, value);
                }
            } else {
                final Field field = fieldInfo.field;

                if (fieldInfo.getOnly) {
                    if (fieldInfo.fieldClass == AtomicInteger.class) {
                        AtomicInteger atomic = (AtomicInteger) field.get(object);
                        if (atomic != null) {
                            atomic.set(((AtomicInteger) value).get());
                        }
                    } else if (fieldInfo.fieldClass == AtomicLong.class) {
                        AtomicLong atomic = (AtomicLong) field.get(object);
                        if (atomic != null) {
                            atomic.set(((AtomicLong) value).get());
                        }
                    } else if (fieldInfo.fieldClass == AtomicBoolean.class) {
                        AtomicBoolean atomic = (AtomicBoolean) field.get(object);
                        if (atomic != null) {
                            atomic.set(((AtomicBoolean) value).get());
                        }
                    } else if (Map.class.isAssignableFrom(fieldInfo.fieldClass)) {
                        Map map = (Map) field.get(object);
                        if (map != null) {
                            if (map == Collections.emptyMap()
                                    || map.getClass().getName().startsWith("java.util.Collections$Unmodifiable")) {
                                // skip
                                return;
                            }
                            map.putAll((Map) value);
                        }
                    } else {
                        Collection collection = (Collection) field.get(object);
                        if (collection != null && value != null) {
                            if (collection == Collections.emptySet()
                                    || collection == Collections.emptyList()
                                    || collection.getClass().getName().startsWith("java.util.Collections$Unmodifiable")) {
                                // skip
                                return;
                            }

                            collection.clear();
                            collection.addAll((Collection) value);
                        }
                    }
                } else {
                    if (field != null) {
                        field.set(object, value);
                    }
                }
            }
        } catch (Exception e) {
            throw new JSONException("set property error, " + clazz.getName() + "#" + fieldInfo.name, e);
        }
    }
}

下面是值修改器介面定義:

import java.lang.annotation.Annotation;

/**
 * @建立人:Raiden
 * @Descriotion:
 * @Date:Created in 22:01 2020/5/1
 * @Modified By: 反序列化值修改器介面
 */
public interface DeserializerValueMutator {

    Object process(Object object, Annotation[] annotations, String name, Object value);
}

反序列化標識註解,只有用這個註解註釋的類才會執行拓展的方法。

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @建立人:Raiden
 * @Descriotion:
 * @Date:Created in 22:25 2020/4/17
 * @Modified By: 反序列化值修改標識註解
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE })
public @interface JsonDeserializer {
    /**
     * 注意這裡只能放無參建構函式的修改器 否則會建立失敗
     * @return
     */
    Class<? extends DeserializerValueMutator>[] valueMutators() default {};
}

強化的JSON序列化工具類:

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.Feature;

import java.lang.reflect.Type;

/**
 * @建立人:Raiden
 * @Descriotion:
 * @Date:Created in 22:12 2020/5/1
 * @Modified By: 反序列化工具類
 */
public final class CustomizeJSON {

    public static <T> T parseObject(String input,Type clazz,DeserializerValueMutator... valueMutators) {
        return JSON.parseObject(input, clazz, new CustomizeParserConfig(valueMutators));
    }

    public static <T> T parseObject(String json, Type type,DeserializerValueMutator[] valueMutators, Feature... features) {
        return JSON.parseObject(json, type, new CustomizeParserConfig(valueMutators), features);
    }

    public static <T> T parseObject(String json, Type type,Feature... features) {
        return JSON.parseObject(json, type, new CustomizeParserConfig(), features);
    }

    public static <T> T parseObject(String json, Type type) {
        return JSON.parseObject(json, type, new CustomizeParserConfig());
    }
}

以上程式碼都可以在我的git中下載:https://github.com/RaidenXin/fastjson-deserializer.git

創作不易,如果轉載請註明出處,小編在此感謝各位看官。

如果覺得有用,請看官們點個贊,謝謝。

 

如果有想學Redis的可以關注我的Redis文章系列:

小白也能看懂的REDIS教學基礎篇——REDIS基礎資料結構

小白也能看懂的REDIS教學基礎篇——朋友面試被SKIPLIST跳躍表攔住了

&n