簡體   English   中英

在Golang中將Struct轉換為JSON

[英]Convert Struct to JSON in Golang

這是Golang的新手,我正在嘗試獲取一種結構,以將其轉換為我的其他應用程序之一將使用的JSON對象。

預期的響應將類似於以下內容...

"access": {
      "STOCK": "1",
      "FOREX": "1",
      "WEBFOREX": "1",
      "WEBSTOCK": "1"
    },
"subscription_group_dates": {
      "32": {
            "START_DATE": 1464753600,
            "END_DATE": 1472616000
            },
      "42": {
            "START_DATE": 1470024000,
            "END_DATE": 1472616000
          }
    }

我已經在對象的“訪問”部分中顯示了我知道的工作部分。 為了簡潔起見,其他所有內容均被省略。 對我來說,最困難的部分是在golang中處理結構的嵌套性質。我認為下面的Struct可以工作,但是我不確定語法。

在SubscriptionGroupDates類型下,我可以使用map [string] struct並將其余部分嵌入如圖所示嗎? 見下文

type UCSUserAccess struct {
    Groups          map[string]string           `json:"groups"`
    Access          map[string]string           `json:"access"`
    IsExpert        string                      `json:"isExpert"`
    SubscriptionGroupDates map[string]struct {
        GroupID struct {
            StartDate map[string]int `START_DATE`
            EndDate   map[string]int `END_DATE`
            }
    } `json:"subscription_group_dates"`
}

另外...我已經在導入部分中導入了“時間”庫。 我將如何使用它來將日期聲明為時間對象? (而不是map [string] int)

謝謝

您的結構有些復雜。 具體來說,SubscriptionGroupDates是字符串到結構的映射,結構本身是字符串到int的映射,或者是具有兩個int字段的靜態結構。 您嵌套了第二個結構,當日期應為整數時,將日期指定為地圖:

type UCSUserAccess struct {
    Groups                 map[string]string  `json:"groups"`
    Access                 map[string]string  `json:"access"`
    IsExpert               string             `json:"isExpert"`
    SubscriptionGroupDates map[string]GroupID `json:"subscription_group_dates"`
}

type GroupID struct {
    StartDate int `json:"START_DATE"`
    EndDate   int `json:"END_DATE"`
}

這提供了您所期望的JSON。 示例: https : //play.golang.org/p/rGm7zKJypk (通過jsonlint.com運行輸出以驗證其是否符合您的要求)。

至於時間戳,您在JSON中的時間戳將存儲為Unix時間戳。 為了使它們進入time.Time,您需要在解組之后或通過在自定義時間類型上實現json.Unmarshaller接口自行解析它們。 有關此操作的詳細信息,請參見此答案

1 -您可以使用MarshalUnmarshal的時候,像這樣的工作示例代碼:

package main

import (
    "encoding/json"
    "fmt"
    "log"
    "strconv"
    "time"
)

type UCSUserAccess struct {
    Groups                 map[string]string `json:"groups"`
    Access                 map[string]string `json:"access"`
    IsExpert               string            `json:"isExpert"`
    SubscriptionGroupDates map[string]struct {
        StartDate Time `json:"START_DATE"`
        EndDate   Time `json:"END_DATE"`
    } `json:"subscription_group_dates"`
}

type Time time.Time

func (t Time) MarshalJSON() ([]byte, error) {
    data := []byte(fmt.Sprint(time.Time(t).UTC().Unix()))
    return data, nil
}
func (t *Time) UnmarshalJSON(data []byte) error {
    i, e := strconv.ParseInt(string(data), 10, 64)
    *t = Time(time.Unix(i, 0).UTC())
    return e
}
func (t Time) String() string {
    return time.Time(t).UTC().String()
}

func main() {
    str := `{ 
"access": {
      "STOCK": "1",
      "FOREX": "1",
      "WEBFOREX": "1",
      "WEBSTOCK": "1"
    },
"subscription_group_dates": {
      "32": {
            "START_DATE": 1464753600,
            "END_DATE": 1472616000
            },
      "42": {
            "START_DATE": 1470024000,
            "END_DATE": 1472616000
          }
    } 
    }`
    var d UCSUserAccess
    err := json.Unmarshal([]byte(str), &d)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(d)

    fmt.Println()
    body, err := json.Marshal(d)
    if err != nil {
        panic(err)
    }
    fmt.Println(string(body))
}

2-您可以使用MarshalUnmarshal時間,例如以下簡化的工作示例代碼:

package main

import (
    "encoding/json"
    "fmt"
    "log"
    "strconv"
    "time"
)

type UCSUserAccess struct {
    StartDate Time `json:"START_DATE"`
}

type Time time.Time

func (t Time) MarshalJSON() ([]byte, error) {
    data := []byte(fmt.Sprint(time.Time(t).UTC().Unix()))
    return data, nil
}
func (t *Time) UnmarshalJSON(data []byte) error {
    i, e := strconv.ParseInt(string(data), 10, 64)
    *t = Time(time.Unix(i, 0).UTC())
    return e
}
func (t Time) String() string {
    return time.Time(t).UTC().String()
}

func main() {
    str := `{ 
            "START_DATE": 1464753600  
    }`
    var d UCSUserAccess
    err := json.Unmarshal([]byte(str), &d)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(d)

    fmt.Println()
    body, err := json.Marshal(d)
    if err != nil {
        panic(err)
    }
    fmt.Println(string(body))
}

3-同樣,您也可以使用int64作為時間,例如以下工作示例代碼:

package main

import (
    "encoding/json"
    "fmt"
    "log"
    "time"
)

type GroupID struct {
    StartDate int64 `json:"START_DATE"`
    EndDate   int64 `json:"END_DATE"`
}

func (t *GroupID) Start() time.Time {
    return time.Unix(t.StartDate, 0)
}
func (t *GroupID) End() time.Time {
    return time.Unix(t.EndDate, 0)
}

type UCSUserAccess struct {
    Access                 map[string]string  `json:"access"`
    SubscriptionGroupDates map[string]GroupID `json:"subscription_group_dates"`
}

func main() {
    str := `{
"access": {
      "STOCK": "1",
      "FOREX": "1",
      "WEBFOREX": "1",
      "WEBSTOCK": "1"
    },
"subscription_group_dates": {
      "32": {
            "START_DATE": 1464753600,
            "END_DATE": 1472616000
            },
      "42": {
            "START_DATE": 1470024000,
            "END_DATE": 1472616000
          }
    }
    }`
    var d UCSUserAccess
    err := json.Unmarshal([]byte(str), &d)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(d)
    gID := d.SubscriptionGroupDates["32"]
    fmt.Println(gID.Start())

    fmt.Println()
    body, err := json.Marshal(d)
    if err != nil {
        panic(err)
    }
    fmt.Println(string(body))
}

4-您可以將Int64與接收器方法一起使用,例如以下工作示例代碼:

package main

import (
    "encoding/json"
    "fmt"
    "log"
    "time"
)

type Int64 int64
type GroupID struct {
    StartDate Int64 `json:"START_DATE"`
    EndDate   Int64 `json:"END_DATE"`
}

func (t *Int64) Time() time.Time {
    return time.Unix(int64(*t), 0).UTC()
}

type UCSUserAccess struct {
    Access                 map[string]string  `json:"access"`
    SubscriptionGroupDates map[string]GroupID `json:"subscription_group_dates"`
}

func main() {
    str := `{
"access": {
      "STOCK": "1",
      "FOREX": "1",
      "WEBFOREX": "1",
      "WEBSTOCK": "1"
    },
"subscription_group_dates": {
      "32": {
            "START_DATE": 1464753600,
            "END_DATE": 1472616000
            },
      "42": {
            "START_DATE": 1470024000,
            "END_DATE": 1472616000
          }
    }
    }`
    var d UCSUserAccess
    err := json.Unmarshal([]byte(str), &d)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(d)
    gID := d.SubscriptionGroupDates["32"]
    fmt.Println(gID.StartDate.Time())

    fmt.Println()
    body, err := json.Marshal(d)
    if err != nil {
        panic(err)
    }
    fmt.Println(string(body))
}

您可以通過提供UnmarshalJSON和MarshalJSON方法來簡單地創建自己的日期。 您可以通過任何方式格式化輸入的句柄並格式化輸出。

package main

import (
    "encoding/json"
    "fmt"
    "strconv"
    "strings"
)

type Date struct {
    year  int
    month int
    day   int
}

func (t *Date) UnmarshalJSON(data []byte) (e error) {
    trimmed := string(data)
    trimmed = strings.TrimLeft(trimmed, "\"")
    trimmed = strings.TrimRight(trimmed, "\"")

    parts := strings.Split(trimmed, "-")

    t.year, _ = strconv.Atoi(parts[0])
    t.month, _ = strconv.Atoi(parts[1])
    t.day, _ = strconv.Atoi(parts[2])

    return
}

func (t *Date) MarshalJSON() (buff []byte, e error) {
    buff = []byte(fmt.Sprintf("\"%d-%d-%d\"", t.year, t.month, t.day))
    return
}

type Foo struct {
    Groups map[string]string `json:"groups"`
    Date   Date              `json:"date"`
}

func main() {

    f := Foo{
        Groups: map[string]string{
            "group1": "bar",
            "group2": "baz",
        },
        Date: Date{year: 2016, month: 12, day: 22},
    }

    buff, _ := json.Marshal(&f)

    fmt.Println(string(buff))

    json.Unmarshal(buff, &f)

    fmt.Printf("%+v", f)

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM