我有一个案例,当请求因某种原因失败时,服务器将使用json错误对象进行响应,服务器始终以HTTP 200响应。因此,如果我的令牌过期并且我请求用户信息,例如:
type Person struct {
FirstName string
LastName string
}
相反得到
{"FirstName": "Bob", "LastName": "Smith"}
我收到了{"error":401, "msg":"Unauthorized"}
我有一个函数,需要interface{}
进行解组:
func (ah *APIHandler) getObjectFromJson(bodyResponse string, target interface{}) *ServerError {
parsingError := json.NewDecoder(strings.NewReader(bodyResponse)).Decode(target)
// when server responds with ServerError I expect to get persingError here and proceed to unmarshalling the error message
if parsingError != nil {
fmt.Println(parsingError.Error())
var err *ServerError = &ServerError{}
parsingError = json.NewDecoder(strings.NewReader(bodyResponse)).Decode(err)
if parsingError != nil {
// this means unmarshalling ServerError failed
panic(parsingError.Error())
}
return err
}
return nil
}
把它放到一个工作示例中,当我提供错误的JSON来传递interface{}
时,我希望在控制台中出现错误“JSON与struct不匹配”,而不是空结构。这可能吗?
我有超过50个模型,所以理想情况下我想避免为每个模型编写unmarshaller以检查字段是否已被正确解组,我也希望避免编写if strings.Contains(responseBody, "error")
,因为某些对象可能包含它们中的字符串错误。
答案 0 :(得分:4)
标准库在解码时始终忽略未映射的字段。这就是您想要的,因为否则您无法在不破坏这些模型的每个消费者的情况下向模型添加新字段。
不是检查无法识别的字段,而是检查响应是否包含错误字段,通过解组两次,或者除了预期的数据之外还解析错误字段。你已经这样做了,但是你反过来了。
func (ah *APIHandler) getObjectFromJson(bodyResponse string, target interface{}) *ServerError {
b := []byte(bodyResponse)
se := &ServerError{}
if err := json.Unmarshal(b, &se); err != nil {
// ...
}
if se.Error != "" {
return se
}
if err := json.Unmarshal(b, target); err != nil {
// ...
}
return nil
}