Tổng quan.
Trong ngôn ngữ lập trình Go (Golang), gói encoding/json
cung cấp hỗ trợ cho việc encode (chuyển đổi) và decode (phục hồi) dữ liệu JSON. JSON (JavaScript Object Notation) là một định dạng dữ liệu phổ biến được sử dụng để truyền thông tin giữa các ứng dụng.
Encode (Chuyển đổi từ Go sang JSON).
Để chuyển đổi dữ liệu từ các loại dữ liệu Go sang chuỗi JSON, bạn có thể sử dụng hàm json.Marshal()
hoặc json.MarshalIndent()
để tạo chuỗi JSON có định dạng đẹp hơn.
Ví dụ:
package main
import (
"encoding/json"
"fmt"
)
type Person struct {
Name string `json:"name"`
Age int `json:"age"`
}
func main() {
person := Person{Name: "John Doe", Age: 30}
// Encode struct to JSON
jsonData, err := json.Marshal(person)
if err != nil {
fmt.Println("Error encoding JSON:", err)
return
}
fmt.Println("Encoded JSON:", string(jsonData))
}
Decode (Phục hồi từ JSON sang Go).
Để phục hồi dữ liệu từ chuỗi JSON sang các kiểu dữ liệu Go, bạn có thể sử dụng hàm json.Unmarshal()
.
Ví dụ:
package main
import (
"encoding/json"
"fmt"
)
type Person struct {
Name string `json:"name"`
Age int `json:"age"`
}
func main() {
// JSON data as a string
jsonData := `{"name":"Jane Doe","age":25}`
// Decode JSON to struct
var person Person
err := json.Unmarshal([]byte(jsonData), &person)
if err != nil {
fmt.Println("Error decoding JSON:", err)
return
}
fmt.Printf("Decoded Person: %+v\n", person)
}
Tùy chỉnh Tên Trường JSON.
Thẻ json
có thể được sử dụng trên các trường struct để chỉ định tên của trường trong JSON:
type Person struct {
Name string `json:"person_name"`
Age int `json:"person_age"`
}
Xử lý Dữ liệu JSON Tự động.
Nếu bạn có dữ liệu JSON mà bạn không biết cấu trúc của nó trước, bạn có thể sử dụng map[string]interface{}
hoặc interface{}
để đại diện cho cấu trúc dữ liệu linh hoạt.
var result map[string]interface{}
err := json.Unmarshal([]byte(jsonData), &result)
Xử lý Array và Slice.
Xử lý dữ liệu JSON chứa mảng hoặc slice được thực hiện bằng cách sử dụng kiểu []interface{}
.
var numbers []int
err := json.Unmarshal([]byte("[1, 2, 3, 4]"), &numbers)
Xử lý Null và Giá trị Mặc định.
Go JSON hỗ trợ kiểu dữ liệu nil để biểu diễn giá trị null trong JSON.
var value *int
err := json.Unmarshal([]byte("null"), &value)
Trên đây chỉ là một số điểm cơ bản về cách sử dụng Go JSON. Gói encoding/json
cung cấp nhiều tính năng và tùy chọn cho việc xử lý JSON trong Go, giúp bạn dễ dàng tương tác với dữ liệu JSON từ các nguồn khác nhau.
3. Ví dụ tổng hợp.
Xem ví dụ tổng hợp sau đây:
package main
import (
"encoding/json"
"fmt"
"os"
)
type response1 struct {
Page int
Fruits []string
}
type response2 struct {
Page int `json:"page"`
Fruits []string `json:"fruits"`
}
func main() {
bolB, _ := json.Marshal(true)
fmt.Println(string(bolB))
intB, _ := json.Marshal(1)
fmt.Println(string(intB))
fltB, _ := json.Marshal(2.34)
fmt.Println(string(fltB))
strB, _ := json.Marshal("gopher")
fmt.Println(string(strB))
slcD := []string{"apple", "peach", "pear"}
slcB, _ := json.Marshal(slcD)
fmt.Println(string(slcB))
mapD := map[string]int{"apple": 5, "lettuce": 7}
mapB, _ := json.Marshal(mapD)
fmt.Println(string(mapB))
res1D := &response1{
Page: 1,
Fruits: []string{"apple", "peach", "pear"}}
res1B, _ := json.Marshal(res1D)
fmt.Println(string(res1B))
res2D := &response2{
Page: 1,
Fruits: []string{"apple", "peach", "pear"}}
res2B, _ := json.Marshal(res2D)
fmt.Println(string(res2B))
byt := []byte(`{"num":6.13,"strs":["a","b"]}`)
var dat map[string]interface{}
if err := json.Unmarshal(byt, &dat); err != nil {
panic(err)
}
fmt.Println(dat)
num := dat["num"].(float64)
fmt.Println(num)
strs := dat["strs"].([]interface{})
str1 := strs[0].(string)
fmt.Println(str1)
str := `{"page": 1, "fruits": ["apple", "peach"]}`
res := response2{}
json.Unmarshal([]byte(str), &res)
fmt.Println(res)
fmt.Println(res.Fruits[0])
enc := json.NewEncoder(os.Stdout)
d := map[string]int{"apple": 5, "lettuce": 7}
enc.Encode(d)
}
Cách đoạn code trên hoạt động như sau:
- Khởi tạo cấu trúc dữ liệu:
- Một số cấu trúc dữ liệu được sử dụng là
response1
vàresponse2
. Chúng đại diện cho dữ liệu có thể được mã hóa và giải mã từ JSON.
- Một số cấu trúc dữ liệu được sử dụng là
- Mã hóa JSON:
- Sử dụng
json.Marshal
để chuyển các giá trị cơ bản (boolean, số nguyên, số thực, chuỗi) và cấu trúc dữ liệu phức tạp (slice, map) thành chuỗi JSON.
- Sử dụng
- Mã hóa cấu trúc dữ liệu tùy chỉnh:
- Sử dụng
json.Marshal
để tự động mã hóa cấu trúc dữ liệu tùy chỉnh (response1
,response2
). Chỉ những trường có chữ cái đầu tiên viết hoa và có thẻ “exported” (có thể truy cập từ bên ngoài gói) mới được mã hóa.
- Sử dụng
- Sử dụng tags JSON để tùy chỉnh key:
- Trong
response2
, sử dụng tagsjson:"..."
để đặt tên khóa JSON khác nhau cho các trường.
- Trong
- Giải mã JSON thành map:
- Sử dụng
json.Unmarshal
để giải mã một đoạn JSON thành một biến map chứa các kiểu dữ liệu đa dạng (map[string]interface{}
).
- Sử dụng
- Chuyển đổi kiểu khi sử dụng giá trị giải mã:
- Do dữ liệu trong map sau khi giải mã có kiểu
interface{}
, nên cần chuyển đổi kiểu để sử dụng chúng. Ví dụ,num := dat["num"].(float64)
.
- Do dữ liệu trong map sau khi giải mã có kiểu
- Giải mã JSON thành cấu trúc dữ liệu tùy chỉnh:
- Sử dụng
json.Unmarshal
để giải mã một đoạn JSON trực tiếp vào một biến kiểu dữ liệu tùy chỉnh (response2
).
- Sử dụng
- Xuất JSON trực tiếp ra đầu ra hoặc writer:
- Sử dụng
json.NewEncoder
để mã hóa JSON trực tiếp ra một writer, ví dụ nhưos.Stdout
. Điều này làm cho quá trình mã hóa có thể được xử lý dần dần mà không cần đợi tất cả dữ liệu được mã hóa xong.
- Sử dụng
Lưu ý, các trường (field) của struct có thể được đánh dấu với các tag json
để chỉ định tên của trường trong JSON và kiểu dữ liệu của trường struct phải tương ứng với kiểu dữ liệu trong JSON.