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做者的代码功底的确很棒。对象

相关文章
相关标签/搜索