Skip to content

Config_cn

Allen edited this page May 28, 2020 · 1 revision

English | 中文

json-iterator提供了一些常用的序列化/反序列化选型供配置,使用者可以根据自己需求打开/关闭特定的选项

配置选项

要配置序列化/反序列化选项,你需要创建一个Config结构体,并通过设置其字段来设置不同的选项,最后你还需要调用其Froze方法来生成这个Config对应的API对象,通过这个API对象来调用你的配置选项对应的序列化/反序列化函数。

api := jsoniter.Config{SortMapKeys:true}.Froze()
api.Marshal(data)

这里我们创建了一个开启了SortMapKeys选项的Config,并生成其对应的API对象,来进行序列化

内置配置

json-iterator提供了三个内置的配置:

  • ConfigDefault

    ConfigDefault是默认配置,它开启了EscapeHTML选项。默认配置的意思是说,当你不创建自己的Config对象并生成API对象,而是直接以类似jsoniter.xxx的方式调用接口时,实际上你的序列化/反序列化使用的就是这个ConfigDefault配置

  • ConfigCompatibleWithStandardLibrary

    ConfigCompatibleWithStandardLibrary开启了EscapeHTMLSortMapKeysValidateJsonRawMessage选项,当你需要近似100%地保证你的序列化/反序列化行为与encoding/json保持一致时,你可以使用这个配置

  • ConfigFastest

    ConfigFastest关闭了EscapeHTML,开启了MarshalFloatWith6DigitsObjectFieldMustBeSimpleString选项,这个配置可以让你的序列化/反序列化达到最高效率,但会有某些限制

选项说明

  • IndentionStep

    指定格式化序列化输出时的空格缩进数量

    type Student struct{
        Name string
        Age int
        Height float32
    }
    
    // 四空格缩进的格式化输出
    c := jsoniter.Config{IndentionStep:4}.Froze()
    if s, err := c.MarshalToString(Student{"Allen", 18, 180.43}); err == nil{
        fmt.Println(s)
        // Output:
        // {
        //     "Name": "Allen",
        //     "Age": 18,
        //     "Height": 180.43
        // }
    }
  • MarshalFloatWith6Digits

    指定浮点数序列化输出时最多保留6位小数

    c := jsoniter.Config{MarshalFloatWith6Digits:true}.Froze()
    if s, err := c.MarshalToString(3.14159265358979); err == nil{
        fmt.Println(s)
        // Output:
        // 3.141593
    }
  • EscapeHTML

    开启了这个选项后,如果你的string类型的变量中含有HTML中使用的特殊字符(如'<','>','&'等),序列化时它们会被转义输出

    type Text struct{
        Html string
    }
    
    c := jsoniter.Config{EscapeHTML:true}.Froze()
    if s, err := c.MarshalToString(Text{`<script>xxx</script>`}); err == nil{
        fmt.Println(s)
        // Output:
        // {"Html":"\u003cscript\u003exxx\u003c/script\u003e"}
    }
  • SortMapKeys

    指定map类型序列化输出时按照其key排序

    rgb := map[string][3]int{
        "yellow":{255, 255, 0},
        "red":{0, 0, 255},
        "green":{0, 255, 0},
        "blue":{0, 0, 255},
    }
    c := jsoniter.Config{SortMapKeys:true}.Froze()
    if s, err := c.MarshalToString(rgb); err == nil{
        fmt.Println(s)
        // 按key的字典序排序输出
        // Output:
        // {"blue":[0,0,255],"green":[0,255,0],"red":[0,0,255],"yellow":[255,255,0]}
    }
  • UseNumber

    指定反序列化时将数字(整数、浮点数)解析成json.Number类型。

    var number interface{}
    c := jsoniter.Config{UseNumber:true}.Froze()
    if err := c.UnmarshalFromString(`3.14159265358979`, &number); err == nil{
        if n, ok := number.(json.Number); ok{
            // 数字被解析成json.Number类型
            f, _ := n.Float64()
            fmt.Println(f)
            // Output:
            // 3.14159265358979
        }
    }
  • DisallowUnknownFields

    当开启该选项时,反序列化过程如果解析到未知字段,即在结构体的schema定义中找不到的字段时,不会跳过然后继续解析,而会返回错误

    type Student struct{
        Name string
        Age int
        Height float32
    }
    
    var std Student
    c := jsoniter.Config{DisallowUnknownFields:true}.Froze()
    // json串中包含未知字段"Weight"
    if err := c.UnmarshalFromString(`{"Name":"Allen","Age":18,"Height":180.43,"Weight":60.56}`, &std); err == nil{
        fmt.Println(std)
    }else{
        fmt.Println(err)
        // Output
        // main.Student.ReadObject: found unknown field: Weight, error found in #10 byte of ...|3,"Weight":60.56}|..., bigger context ...|{"Name":"Allen","Age":18,"Height":180.43,"Weight":60.56}|...
    }
  • TagKey

    指定tag字符串,默认情况为"json",我们可以指定成另一个字符串

    type Student struct{
        Name string `jsoniter:"name"`
        Age int
        Height float32 `jsoniter:"-"`
    }
    
    // 将tag指定为"jsoniter"
    c := jsoniter.Config{TagKey:"jsoniter"}.Froze()
    if s, err := c.MarshalToString(Student{"Allen", 18, 180.43}); err == nil{
        fmt.Println(s)
        // Output:
        // {"name":"Allen","Age":18}
    }
  • OnlyTaggedField

    当开启该选项时,只有带上tag的结构体字段才会被序列化输出

    type Student struct{
        Name string `json:"name"`
        Age int
        Height float32 `json:",omitempty"`
    }
    
    c := jsoniter.Config{OnlyTaggedField:true}.Froze()
    if s, err := c.MarshalToString(Student{"Allen", 18, 180.43}); err == nil{
        fmt.Println(s)
        // Age字段没有tag,不会编码输出
        // Output:
        // {"name":"Allen","Height":180.43}
    }
  • ValidateJsonRawMessage

    json.RawMessage类型的字段在序列化时会原封不动地进行输出。开启这个选项后,json-iterator会校验这种类型的字段包含的是否一个合法的json串,如果合法,原样输出;否则会输出"null"

    type Book struct{
        Pages int
        Name string
        Description json.RawMessage
    }
    
    c := jsoniter.Config{ValidateJsonRawMessage:true}.Froze()
    if s, err := c.MarshalToString(Book{361, "X",json.RawMessage(`{"Category":`)}); err == nil{
        fmt.Println(s)
        // Description 字段为非法json串,输出null
        // Output:
        // {"Pages":361,"Name":"X","Description":null}
    }
  • ObjectFieldMustBeSimpleString

    开启该选项后,反序列化过程中不会对你的json串中对象的字段字符串可能包含的转义进行处理,因此你应该保证你的待解析json串中对象的字段应该是简单的字符串(不包含转义)

    type Student struct{
        Name string
        Age int
        Height float32
    }
    
    var std Student
    c := jsoniter.Config{ObjectFieldMustBeSimpleString:true}.Froze()
    if err := c.UnmarshalFromString(`{"Name":"Allen","Ag\u0065":18,"Height":180.43}`, &std); err == nil{
        fmt.Println(std)
        // Age字段的转义不会处理,因此该字段无法解析出来
        // Output:
        // {Allen 0 180.43}
    }
  • CaseSensitive

    开启该选项后,你的待解析json串中的对象的字段必须与你的schema定义的字段大小写严格一致

    type Student struct{
        Name string
        Age int
        Height float32
    }
    
    var std Student
    c := jsoniter.Config{CaseSensitive:true}.Froze()
    if err := c.UnmarshalFromString(`{"Name":"Allen","Age":18,"height":180.43}`, &std); err == nil{
        fmt.Println(std)
        // Height字段的大小写不一致,无法解析出来
        // Output:
        // {Allen 18 0}
    }