自定义解组golang - object或int

qltillow  于 2023-04-18  发布在  Go
关注(0)|答案(1)|浏览(118)

我尝试将API的响应分解为一个公共结构,如下所示:

"status": {
        "title"
        "statusCode"
        "detail"
    }

例如,status将Map到statusCode

Below 2 type of responses from API:
{
    "status": {
        "title": "Bad Request",
        "statusCode": 400,
        "detail": "Your request contained technical errors as listed below."
    },
    "items": [
        {
            "propertyPath": "shipments[0].services.visualCheckOfAge",
            "message": "Parameter visualCheckOfAge only allows the values A16 or A18."
        }
    ]
}

{
    "status": 401,
    "title": "Unauthorized",
    "detail": "Unauthorized for given resource."
}

我试过像这样的自定义解组,但失败了:

type ShipmentOrderResponse struct {
    Status Status  `json:"status"`
    Title  string  `json:"title,omitempty"`
    Detail string  `json:"detail,omitempty"`
    Items  *[]Item `json:"items,omitempty"`
}

type Status struct {
    Title string `json:"title,omitempty"`
    Code  int    `json:"statusCode,omitempty"`
    // Instance A URI reference that identifies the specific occurrence of the problem.
    Instance string `json:"instance,omitempty"`
    // Detail Defines details about the status of the response.
    Detail string `json:"detail,omitempty"`
}
func (s *Status) UnmarshalJSON(d []byte) error {
    for _, b := range d {
        switch b {
        // These are the only valid whitespace in a JSON object.
        case ' ', '\n', '\r', '\t':
        case '{':
            var obj Status
            if err := json.Unmarshal(d, &obj); err != nil {
                return err
            }
            *s = obj
            return nil
        default:
            var code int
            err := json.Unmarshal(d, &code)
            if err != nil {
                return err
            }
            s.Code = code
            return nil
        }
    }
    return errors.New("status must be object or int")
}

任何提示,我会很感激,如何解决这个问题。
谢谢。

6kkfgxo0

6kkfgxo01#

使用此方法。

func (s *Status) UnmarshalJSON(d []byte) error {
    // Is it an object? 
    if d[0] == '{' {
        // Define a type to break recursion. Type X has the same
        // fields as Status, but no methods. In particular, type
        // X does not have a UnmarshalJSON method.
        type X Status
        return json.Unmarshal(d, (*X)(s))
    }
    // Assume an integer.
    return json.Unmarshal(d, &s.Code)
}

https://go.dev/play/p/FN9q3E7ox0u
跳过问题中的空白的循环是不需要的,因为UnmarshalJSON的数据参数不包括值之前的空白。

相关问题