Saturday, January 18, 2025

[Golang] Phần 18 – Go JSON

-

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à response1response2. Chúng đại diện cho dữ liệu có thể được mã hóa và giải mã từ JSON.
  • 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.
  • 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 tags JSON để tùy chỉnh key:
    • Trong response2, sử dụng tags json:"..." để đặt tên khóa JSON khác nhau cho các trường.
  • 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{}).
  • 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).
  • 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).
  • 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.

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.

LEAVE A REPLY

Please enter your comment!
Please enter your name here

4,956FansLike
256FollowersFollow
223SubscribersSubscribe
spot_img

Related Stories