如何将输入作为 json 字符串,然后根据条件将其转换为任何对象

How to take input as json string and later convert it to any object based on condition

这里我想将 DefaultResponse 作为字符串,但稍后在映射到任何 json 结构之前验证它是否有效 json。

可在此处找到带验证的完整代码: https://go.dev/play/p/knGNMj1QG3l

type AddEndpointRequest struct {
    Method            string `json:"method"`
    ContentType       int    `json:"contentType"`
    DefaultStatusCode int    `json:"defaultStatusCode"`
    DefaultResponse   string `json:"defaultResponse"`
}

我尝试了不同的选项,但 none 个选项有效

  1. 如果我通过这个:“defaultResponse”:{“title”:“早餐买奶酪和面包。”} 出现错误:json:无法将对象解组到字符串类型

    的 Go 结构字段 AddEndpointRequest.defaultResponse

正文 := {"method":"GET","contentType":1,"defaultWaitTimeInMillis":100,"defaultStatusCode":200,"defaultResponse":"[{"p":"k"}]"}

错误:对象 key:value 对

后的字符 'p' 无效

3) 正文 := {"method":"GET","contentType":1,"defaultWaitTimeInMillis":100,"defaultStatusCode":200,"defaultResponse":"{"p":"k"}"} ./prog.go:21:117: 语法错误:意外的 { 在语句结尾

  1. body := {"method":"GET","contentType":1,"defaultWaitTimeInMillis":100,"defaultStatusCode":200,"defaultResponse":"{/"p/":/"k/"}"} Error : ./prog.go:21:130: syntax error: unexpected literal "} 在语句末尾

还有更多

选项A:

将字段声明为字符串。使用有效的 JSON 字符串作为文档中的字段值。注意字符串中引号的转义。

type AddEndpointRequest struct {
    Method            string          `json:"method"`
    ContentType       int             `json:"contentType"`
    DefaultStatusCode int             `json:"defaultStatusCode"`
    DefaultResponse   string          `json:"defaultResponse"`
}
…
body := `{"method":"GET","contentType":1,"defaultWaitTimeInMillis":100,"defaultStatusCode":200,"defaultResponse":"{\"p\":\"k\"}"}`

将字段转换为 [] 字节以解组:

err := json.Unmarshal([]byte(request.DefaultResponse), &data)

https://go.dev/play/p/ailgQQ3eQBH

选项B:

将字段声明为 json.RawMessage。在文档中使用任何有效的 JSON。

type AddEndpointRequest struct {
    Method            string          `json:"method"`
    ContentType       int             `json:"contentType"`
    DefaultStatusCode int             `json:"defaultStatusCode"`
    DefaultResponse   json.RawMessage `json:"defaultResponse"`
}
…
body := `{"method":"GET","contentType":1,"defaultWaitTimeInMillis":100,"defaultStatusCode":200,"defaultResponse":{"p":"k"}}`

调用 json.Unmarshal([]byte(body), &request) 验证 json.RawMessage 字段。如果对 json.Unmarshal 的调用没有 return 错误,则可以确保应用程序 AddEndpointRequest.DefaultResponse 包含有效的 JSON.

像这样解组字段:

err := json.Unmarshal(request.DefaultResponse, &data)

https://go.dev/play/p/Xd_gWzJmvC_K

如果你想在 defaultResponse 中设置一个结构,我认为这样做应该可行。

package main

import (
    "encoding/json"
    "errors"
    "fmt"
)

type AddEndpointRequest struct {
    Method            string `json:"method"`
    ContentType       int    `json:"contentType"`
    DefaultStatusCode int    `json:"defaultStatusCode"`
    DefaultResponse   string `json:"defaultResponse"`
}

func main() {

    body := `{"method":"GET","contentType":1,"defaultWaitTimeInMillis":100,"defaultStatusCode":200,"defaultResponse":{"title":"Buy cheese and bread for breakfast."}}`
    fmt.Println("Hello GO")

    err := validateBody(body)
    if err != nil {
        fmt.Println("erro102")
        fmt.Println(err)

    }
}

func validateBody(body string) error {
    var data map[string]interface{}
    err := json.Unmarshal([]byte(body), &data)
    if err != nil {
        return errors.New("invalid json body provided for the request")
    }

    fmt.Println("data===>", data)

    fmt.Println("defaultResponse===>", data["defaultResponse"].(map[string]interface{})["title"])

    return nil
}