jsongomarshallingunmarshalling

Check JSON string valid or not in golang


I want to check whether an interface that comes from my application is valid json or not. I have searched. It could be duplicate of here: duplicate (but it did not work) I found some methods. One of them is Marshaling then Unmarshaling the interface like the following code:

func isJSONClasic(i interface{}) bool {
    x, err := json.Marshal(i)
    if err != nil {
        fmt.Printf("error: %+v\n", err)
    }
    var temp interface{}
    return json.Unmarshal(x, &temp) == nil
}

Another method I used is gjson package. According to its documentation in here, it has ValidBytes method. It takes a byte arrray and returns the validation. The function I used is like following:

func isJSONGjson(i interface{}) bool {
    x, err := json.Marshal(i)
    if err != nil {
        fmt.Printf("error: %+v\n", err)
    }
    return gjson.ValidBytes(x)
}

The sample data I used is {"name""latif"}. It is easy to see that it is not a valid json. (Also I tested in here) When I test the data with the 2 functions, I expected that they should print false as the result of the validation, but I get true for both of them. The whole code I tested and result is like following: package main

package main

import (
    "encoding/json"
    "fmt"

    "github.com/tidwall/gjson"
)

func main() {
    var data interface{}
    data = `{"name""latif"}`

    isValid := isJSONClasic(data)
    fmt.Printf("%+v\n", isValid)

    isValid = isJSONGjson(data)
    fmt.Printf("%+v\n", isValid)
}

func isJSONClasic(i interface{}) bool {
    x, err := json.Marshal(i)
    if err != nil {
        fmt.Printf("error: %+v\n", err)
    }
    var temp interface{}
    return json.Unmarshal(x, &temp) == nil
}

func isJSONGjson(i interface{}) bool {
    x, err := json.Marshal(i)
    if err != nil {
        fmt.Printf("error: %+v\n", err)
    }
    return gjson.ValidBytes(x)
}

The output is following:

enter image description here

Even the sample data is not valid, I get true. What is wrong in here? How can I learn a json is valid or not with golang?


Solution

  • Here an example:

    package main
    
    import (
        "bytes"
        "encoding/gob"
        "encoding/json"
        "fmt"
    )
    
    func main() {
        var data interface{}
        data = `{"name""latif"}`
        valid := `{"name":"latif"}`
    
        isValid := isValidJSON(data)
        fmt.Printf("%+v\n", isValid)
        isValid = isValidJSON(valid)
        fmt.Printf("%+v\n", isValid)
    }
    
    func isValidJSON(i interface{}) bool {
        var str map[string]string
        data, err := getBytes(i)
        if err != nil {
            panic(err.Error())
        }
        data = data[4:]
        err = json.Unmarshal(data, &str)
        return err == nil
    }
    
    func getBytes(i interface{}) ([]byte, error) {
        var buf bytes.Buffer
        enc := gob.NewEncoder(&buf)
        err := enc.Encode(i)
        if err != nil {
            return nil, err
        }
        return buf.Bytes(), nil
    }
    

    Note: The first 4 byte after the encoding of the interface to []byte have to be removed


    Result:

    false
    true