簡體   English   中英

json:無法將 object 解組為 []*main.Config 類型的 Go 值

[英]json: cannot unmarshal object into Go value of type []*main.Config

我是 golang 和 json 的新手,我們正在使用大猩猩 mux 庫,我想在 postman 中執行發布請求。在配置結構中,條目需要像這樣的 map,在發布服務器中,我需要有一個數組*在 postServer 結構中配置。 我有 3 個 go 文件。 Service.go文件是這樣的:

package main

import (
"errors"
"github.com/gorilla/mux"
"mime"
"net/http"
)

type Config struct {
  Id      string            `json:"id"`
  entries map[string]string `json:"entries"`
}

type postServer struct {
  data map[string][]*Config
}

func (ts *postServer) createPostHandler(w http.ResponseWriter, req *http.Request) {
   contentType := req.Header.Get("Content-Type")
   mediatype, _, err := mime.ParseMediaType(contentType)
   if err != nil {
    http.Error(w, err.Error(), http.StatusBadRequest)
    return
}

if mediatype != "application/json" {
    err := errors.New("Expect application/json Content-Type")
    http.Error(w, err.Error(), http.StatusUnsupportedMediaType)
    return
}

rt, err := decodeBody(req.Body)
if err != nil {
    http.Error(w, err.Error(), http.StatusBadRequest)
    return
}

id := createId()
ts.data[id] = rt
renderJSON(w, rt)
}

func (ts *postServer) getAllHandler(w http.ResponseWriter, req *http.Request) {
allTasks := []*Config{}
for _, v := range ts.data {
    allTasks = append(allTasks, v...)
}

renderJSON(w, allTasks)
}
func (ts *postServer) getPostHandler(w http.ResponseWriter, req *http.Request) {
id := mux.Vars(req)["id"]
task, ok := ts.data[id]
if !ok {
    err := errors.New("key not found")
    http.Error(w, err.Error(), http.StatusNotFound)
    return
}
renderJSON(w, task)
}

func (ts *postServer) delPostHandler(w http.ResponseWriter, req *http.Request) {
id := mux.Vars(req)["id"]
if v, ok := ts.data[id]; ok {
    delete(ts.data, id)
    renderJSON(w, v)
} else {
    err := errors.New("key not found")
    http.Error(w, err.Error(), http.StatusNotFound)
}
}

我想測試 createPostHandler。 然后我有 helper.go 文件,我在其中將 json 解碼為 go 並呈現為 json:

package main

import (
"encoding/json"
"github.com/google/uuid"
"io"
"net/http"
)

func decodeBody(r io.Reader) ([]*Config, error) {
dec := json.NewDecoder(r)
dec.DisallowUnknownFields()

var rt []*Config
if err := dec.Decode(&rt); err != nil {
    return nil, err
}
return rt, nil
}

func renderJSON(w http.ResponseWriter, v interface{}) {
js, err := json.Marshal(v)
if err != nil {
    http.Error(w, err.Error(), http.StatusInternalServerError)
    return
}

w.Header().Set("Content-Type", "application/json")
w.Write(js)
}

func createId() string {
return uuid.New().String()
}

最后一個 go 文件是 main.go 我有這個:

package main

import (
"context"
"github.com/gorilla/mux"
"log"
"net/http"
"os"
"os/signal"
"syscall"
"time"
)

func main() {
quit := make(chan os.Signal)
signal.Notify(quit, os.Interrupt, syscall.SIGTERM)

router := mux.NewRouter()
router.StrictSlash(true)

server := postServer{
    data: map[string][]*Config{},
}
router.HandleFunc("/config/", server.createPostHandler).Methods("POST")
router.HandleFunc("/configs/", server.getAllHandler).Methods("GET")
router.HandleFunc("/config/{id}/", server.getPostHandler).Methods("GET")
router.HandleFunc("/config/{id}/", server.delPostHandler).Methods("DELETE")

// start server
srv := &http.Server{Addr: "0.0.0.0:8000", Handler: router}
go func() {
    log.Println("server starting")
    if err := srv.ListenAndServe(); err != nil {
        if err != http.ErrServerClosed {
            log.Fatal(err)
        }
    }
}()

<-quit

log.Println("service shutting down ...")

// gracefully stop server
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()

if err := srv.Shutdown(ctx); err != nil {
    log.Fatal(err)
}
log.Println("server stopped")

}

我發送的 JSON 是這樣的:

{
"entries":["hello", "world"]
}

我在 postman 中得到的錯誤是:

json: cannot unmarshal object into Go value of type []*main.Config

我不知道有什么問題,也許我發送了錯誤的 json 或者我只是在 decodeBody 中做錯了什么,我需要在 var rt []*Config 的 decodeBody 中添加 [],因為否則它不會工作。 有人可以幫我解決這個問題嗎?

這是一個示例,說明如何定義可以將樣本 JSON 解析到的結構 Config。

編輯:字段entries更改為 map。

你可以在Playground上玩它。

package main

import (
    "encoding/json"
    "fmt"
)

type Config struct {
    Id      string            `json:"id"`
    Entries map[string]string `json:"entries"`
}

func main() {
    str := `[{"id":"42", "entries":{"hello": "world"}}]`
    var tmp []Config
    err := json.Unmarshal([]byte(str), &tmp)
    if err != nil {
        fmt.Printf("error: %v", err)
    }
    var rt []*Config
    for _, c := range tmp {
        rt = append(rt, &c)
    }
    for _, c := range rt {
        for k, v := range c.Entries {
            fmt.Printf("id=%s key=%s value=%s\n", c.Id, k, v)
        }
    }
}

暫無
暫無

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

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