fastjson SerializerFeature

public enum SerializerFeature {
	/**
	 * 對鍵加雙引號
	 */
    QuoteFieldNames,
    /**
     * 使用單引號代替雙引號
     */
    UseSingleQuotes,
    /**
     * 輸出空值(null)
     */
    WriteMapNullValue,
    /**
     * 用枚舉toString()值輸出
     */
    WriteEnumUsingToString,
    /**
     * 用枚舉name()輸出
     */
    WriteEnumUsingName,
    /**
     * 對日期進行2016-09-23T23:11:56.550這樣的格式化
     */
    UseISO8601DateFormat,
    /**
     * @since 1.1
     * 若是一個List(實現了List接口)爲null 則輸出[]
     */
    WriteNullListAsEmpty,
    /**
     * @since 1.1
     * 若是一個字符串爲null,則輸出""
     */
    WriteNullStringAsEmpty,
    /**
     * @since 1.1
     * 數字字段輸出0 而不是null
     */
    WriteNullNumberAsZero,
    /**
     * @since 1.1
     * 若是一個Boolean變量爲null,則輸出false
     */
    WriteNullBooleanAsFalse,
    /**
     * @since 1.1
     * 不輸出transient修飾的變量
     */
    SkipTransientField,
    /**
     * @since 1.1
     * 對字段進行排序
     */
    SortField,
    /**
     * @since 1.1.1
     */
    @Deprecated
    WriteTabAsSpecial,
    /**
     * @since 1.1.2
     * 格式化輸出
     */
    PrettyFormat,
    /**
     * @since 1.1.2
     * 輸出類的名字
     */
    WriteClassName,

    /**
     * @since 1.1.6
     * 對於值相同的鍵,不使用引用表達
     * 不使用相似於下面的方式來輸出:
     * {"$ref":"$"} 	引用根對象
     * {"$ref":"@"} 	引用本身
     * {"$ref":".."} 	引用父對象
     * {"$ref":"../.."} 	引用父對象的父對象
     * {"$ref":"$.members[0].reportTo"} 	基於路徑的引用
     */
    DisableCircularReferenceDetect,

    /**
     * @since 1.1.9
     * 把正斜線/當作特殊字符
     */
    WriteSlashAsSpecial,

    /**
     * @since 1.1.10
     * 爲了瀏覽器兼容問題,把中文轉換爲\u4E2D這樣的Unicode碼
     */
    BrowserCompatible,

    /**
     * @since 1.1.14
     * 使用2016-09-19 16:19:05這樣的格式格式化日期
     */
    WriteDateUseDateFormat,

    /**
     * @since 1.1.15
     */
    NotWriteRootClassName,

    /**
     * @since 1.1.19
     * 對特殊字符進行轉義,例如" 換爲\"
     */
    DisableCheckSpecialChar,

    /**
     * @since 1.1.35
     * 按["field1",field2,field3,"field4","field5","field6"]
     * 這樣的格式來輸出bean
     */
    BeanToArray,

    /**
     * @since 1.1.37
     * 把全部的鍵都做爲String
     */
    WriteNonStringKeyAsString,
    
    /**
     * @since 1.1.42
     * 不輸出默認值
     */
    NotWriteDefaultValue,
    
    /**
     * @since 1.2.6
     */
    BrowserSecure,
    
    /**
     * @since 1.2.7
     * 忽略沒有getter的字段
     */
    IgnoreNonFieldGetter
    ;

    SerializerFeature(){
        mask = (1 << ordinal());
    }

    private final int mask;

    public final int getMask() {
        return mask;
    }

    /**
     * 判斷features所表明的特性集合中是否包含有feature特性
     * 這裏巧妙的使用了一個掩碼(mask)來計算,mask是經過對1進行移位獲得的
     * 由於每個SerializerFeature在枚舉中的序數是固定的,因此mask的
     * 值就是像下面的二進制形式:
     * 00000000000000000000000000000001
     * 00000000000000000000000000000010
     * 00000000000000000000000000000100
     * 00000000000000000000000000001000
     * ......
     * 10000000000000000000000000000000
     * 因此經過&運算很容易就判斷出features中有沒有feature。例如:
     * feature是WriteMapNullValue(0000000000000000000000000000100),
     * features是15(0000000000000000000000000001111),很容易知道features
     * 中包含有feature。(可經過SerializerFeature數組計算features,下面提供的
     * of方法就能夠計算features的值(SerializerFeature數組的掩碼(mask)))
     * @param features
     * @param feature
     * @return
     */
    public static boolean isEnabled(int features, SerializerFeature feature) {
        return (features & feature.getMask()) != 0;
    }
    
    /**
     * 檢查features或者fieaturesB是否包含feature
     * 和上一個方法同樣
     * @param features
     * @param fieaturesB
     * @param feature
     * @return
     */
    public static boolean isEnabled(int features, int fieaturesB, SerializerFeature feature) {
        int mask = feature.getMask();
        
        return (features & mask) != 0 || (fieaturesB & mask) != 0;
    }

    /**
     * 爲features增長feature特性,或者剔除feature特性
     * 當state爲true時爲features增長feature特性
     * 當state爲false時爲features剔除feature特性
     * @param features
     * @param feature
     * @param state
     * @return
     */
    public static int config(int features, SerializerFeature feature, boolean state) {
        if (state) {
            features |= feature.getMask();
        } else {
            features &= ~feature.getMask();
        }

        return features;
    }
    
    /**
     * 計算SerializerFeature數組的掩碼(mask)
     * 經過|運算把features中的特性疊加起來
     * @param features
     * @return
     */
    public static int of(SerializerFeature[] features) {
        if (features == null) {
            return 0;
        }
        
        int value = 0;
        
        for (SerializerFeature feature: features) {
            value |= feature.getMask();
        }
        
        return value;
    }
}

SerializerFeature是一個枚舉類型,如今包含有17個枚舉值。能夠經過每個枚舉值來控制在轉化爲json字符串的行爲。比較經常使用的是:java

WriteNullStringAsEmpty  若是一個字符串爲null,則輸出""json

WriteNullNumberAsZero 數字字段輸出0 而不是null數組

DisableCircularReferenceDetect  不使用應用表達瀏覽器

WriteDateUseDateFormat  使用2016-09-19 16:19:05這樣的格式格式化日期學習

SerializerFeature中使用的技巧也是很是值得學習的,例如,在isEnable中巧妙的使用了一個掩碼(mask)來計算,mask是經過對1進行移位獲得的由於每個SerializerFeature在枚舉中的序數是固定的,因此mask的值就是像下面的二進制形式:
     00000000000000000000000000000001
     00000000000000000000000000000010
     00000000000000000000000000000100
     00000000000000000000000000001000
     ......
     10000000000000000000000000000000
     因此經過&運算很容易就判斷出features中有沒有feature。例如:
     feature是WriteMapNullValue(0000000000000000000000000000100),
     features是15(0000000000000000000000000001111),很容易知道features
     中包含有feature。(可經過SerializerFeature數組計算features,下面提供的
     of方法就能夠計算features的值(SerializerFeature數組的掩碼(mask)))code

既然提到了of方法就先說of方法。首先SerializerFeature中的枚舉值是兼容的而不是相互排斥的,例如,既要若是一個字符串爲null,則輸出"",又要使用2016-09-19 16:19:05這樣的格式格式化日期,那麼就WriteNullStringAsEmpty,WriteDateUseDateFormat  這兩個枚舉值,在fastjson中能夠經過SerializerFeature數組來表示。而fastjson中不少時候是經過一個int類型的數字來表示,根據前面提到的很容易想到對WriteNullStringAsEmpty,WriteDateUseDateFormat  的mask作亦或(|)運算,而實際上SerializerFeature的of方法就是這麼幹的。因此須要isEnable方法來判讀一個int類型的值中是否是包含有某一個SerializerFeature。orm

很天然的咱們想到要爲一個features增長一個feature或者從features中剔除一個feature,因而config方法來了。先說添加features |= feature.getMask();一句代碼就搞定了,若是你把前面isEnable的註釋讀清楚了這句就很好理解了,先獲取到要添加feature的mask,在作一回運算,亦或運算時只要有一個是1就是1,就是若是features對應位上沒有1就把它置爲1。同理,從features中剔除feature也是一句代碼features &= ~feature.getMask();&運算的特色是有一個爲0就爲0,這裏先把要剔除的feature的mask而後取反,就是把該feature對應位上置0,而後利用&運算的特色把features中feature對應位上的值置0。config的代碼很是簡潔,不得不說fastjson做者的代碼功底的確很棒。對象

相關文章
相關標籤/搜索