首页 > 解决方案 > 如何将一段结构编组为有效的 JSON

问题描述

我正在编写一个 Golang api 和客户端,但无法从 api 中的一片结构中获取有效的 json。我在客户中得到的结果如下所示。

[{0 马克 1234 错误} {0 约翰 3456 错误}]

我需要这个 json 看起来像

[{"id":0, "name":Mark, "pin":1234, "active":false} {"id":0, "name":John, "pin":3456, "active":false }]

我找不到向我展示如何正确编码的示例,尽管有警告,但这并不是我能找到的任何内容的重复。虽然我的客户端成功地将 JSON 解析回结构,但我需要它将 JSON 返回到请求它的 IOS 客户端。流程是 API -> API -> iOS 客户端。我不知道如何从 iOS 客户端的结构中生成 JSON。

这是我的api代码。

// Employee model
type Employee struct {
    EmployeeID int64  `json:"id"`
    Name       string `json:"name"`
    Pin        int    `json:"pin"`
    Active     bool   `json:"active"`
}

func getEmployees(db *sql.DB, venueID int64) ([]Employee, error) {

    var employee Employee

    var employees []Employee

    query, err := db.Query("SELECT id, name, pin FROM employees WHERE active=1 AND venue_id=? ORDER BY name", venueID)
    if err != nil {
        return employees, err
    }

    defer query.Close()

    for query.Next() {
        err = query.Scan(&employee.EmployeeID, &employee.Name, &employee.Pin)
        if err != nil {
            return employees, err
        }
        employees = append(employees, employee)
    }

    return employees, err
}



func (rs *appResource) listEmployees(w http.ResponseWriter, r *http.Request) {

    var venue Venue

    token := getToken(r)

    fmt.Println(token)

    venue, err := getVenue(rs.db, token)

    if err != nil {
        log.Fatal(err)
        return
    }

    venueID := venue.VenueID

    if !(venueID > 0) {
        http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
        return
    }

    employees, err := getEmployees(rs.db, venueID)

    if err != nil {
        log.Fatal(err)
        return
    }

    fmt.Println(employees[0].EmployeeID)

    employeesJSON, err := json.Marshal(employees)
    if err != nil {
        log.Fatal(err)
        return
    }

    w.Write([]byte(employeesJSON))

}

这是我的客户代码:

func (rs *appResource) getEmployees(w http.ResponseWriter, r *http.Request) {

    path := rs.url + "/employees"

    fmt.Println(path)

    res, err := rs.client.Get(path)

    if err != nil {
        log.Println("error in get")
        log.Fatal(err)
        http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
        return
    }

    defer res.Body.Close()

    if res.StatusCode == 500 {
        fmt.Printf("res.StatusCode: %d\n", res.StatusCode)
        http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
        return

    }

    if res.StatusCode == 404 {
        fmt.Printf("res.StatusCode: %d\n", res.StatusCode)
        http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
        return
    }

    body, err := ioutil.ReadAll(res.Body)
    if err != nil {
        log.Fatal(err)
        http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
        return
    }

// here I want to return actual JSON to an iOS client    

    w.WriteHeader(http.StatusOK)
    w.Write([]byte("{ok}"))
}

标签: go

解决方案


我实际上很惊讶您的代码正在运行,因为您有 2 个未使用的变量(错误,错误在 listEmployees)。任何应该工作的方式,添加一个 fmt.Println 这样你就可以在控制台上看到结果

 type Employee struct {
        ID     int    `json:"id"`
        Name   string `json:"name"`
        Pin    int    `json:"pin"`
        Active bool   `json:"active"`
    }

    func (rs *appResource) listEmployees(w http.ResponseWriter, r *http.Request) {
        employees, _:= getEmployees(rs.db)
        employeesJSON, _:= json.Marshal(employees)
        fmt.Ptintln(string(employeesJSON))
        w.Write(employeesJSON)
    }

另一个运行示例:

func main() {
    emp := Employee{
        ID:     1,
        Name:   "Mark",
        Pin:    1234,
        Active: true,
    }
    if jsn, err := json.Marshal(emp); err == nil {
        fmt.Println(string(jsn))
    } else {
        log.Panic(err)
    }

}

type Employee struct {
    ID     int    `json:"id"`
    Name   string `json:"name"`
    Pin    int    `json:"pin"`
    Active bool   `json:"active"`
}

输出:

{"id":1,"name":"Mark","pin":1234,"active":true}


推荐阅读