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:
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?
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