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

Time:06-02

Here I want to take DefaultResponse as String but later validate if it's a valid json before mapping to any json struct.

Complete code with validation can be found here : 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"`
}

I tried different option but none of them are working

  1. if I pass this : “defaultResponse”:{“title”:“Buy cheese and bread for breakfast.”} Getting error : json: cannot unmarshal object into Go struct field AddEndpointRequest.defaultResponse of type string

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

Error : invalid character 'p' after object key:value pair

3) body := {"method":"GET","contentType":1,"defaultWaitTimeInMillis":100,"defaultStatusCode":200,"defaultResponse":"{"p":"k"}"} ./prog.go:21:117: syntax error: unexpected { at end of statement

  1. body := {"method":"GET","contentType":1,"defaultWaitTimeInMillis":100,"defaultStatusCode":200,"defaultResponse":"{/"p/":/"k/"}"} Error : ./prog.go:21:130: syntax error: unexpected literal "} at end of statement

And many more

CodePudding user response:

Option A:

Declare the field as a string. Use a valid JSON string as the field value in the document. Note the escaping of the quotes in the string.

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\"}"}`

Convert the field to a []byte to unmarshal:

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

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

Option B:

Declare the field as json.RawMessage. Use any valid JSON in the document.

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"}}`

The call to json.Unmarshal([]byte(body), &request) validates the json.RawMessage field. If the call to json.Unmarshal does not return an error, then the application is assured that AddEndpointRequest.DefaultResponse contains valid JSON.

Unmarshal the field like this:

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

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

CodePudding user response:

If you want to set a struct in defaultResponse, I think doing it like this should work.

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
}

  • Related