猿问

如何在Golang Rest中输出json格式错误,特别是引用坏字段

我有以下要求:从 REST API 返回以下格式的错误:


Error format

422

{

    "name-of-field": [

        "can't be blank",

        "is too silly"

    ]

}

我的代码如下所示:


var PostFeedback = func(w http.ResponseWriter, r *http.Request) {

    params := mux.Vars(r)

    surveyId := params["id"]

    feedback := &models.Feedback{}

    err := json.NewDecoder(r.Body).Decode(feedback)

    if err != nil {

        jsonError := fmt.Sprintf(`{

            "%s": [

                "%s"

            ]

        }`, "errors", err)

        log.Printf("invalid input format, %v", jsonError)

        resp := map[string]interface{}{"error": jsonError}

        u.Respond(w, resp)

        return

    }

问题:


如何获取违规字段的名称?

我怎样才能最好地满足要求?


LEATH
浏览 122回答 0
0回答

慕仙森

该encoding/json包不提供对“空白”或“愚蠢”值的验证。仅当正文中的数据不是有效的 json,或者根据包的规范,json 中的字段类型与您尝试解码的结构的字段类型不匹配时,它才会返回错误那个 json。第一种类型的错误是json.SyntaxError,如果您遇到此错误,则并不总是能够满足您的要求,因为可能没有您可以在响应中使用的实际字段,或者如果有 json 字段、它们及其值,可能是完全有效的 json,但错误的原因可能在其他地方(参见示例)。例如,如果数据包含实际的 json 字段,但它具有非 json 值,您可以使用该类型Offset的字段SyntaxError来查找数据流中最接近的前面的字段。使用strings.LastIndex您可以实现一个简单的解决方案来向后查找该字段。data := []byte(`{"foobar": i'm not json}`)err := json.Unmarshal(data, &T{})se, ok := err.(*json.SyntaxError)if !ok {    panic(err)}field := string(data[:se.Offset])if i := strings.LastIndex(field, `":`); i >= 0 {    field = field[:i]    if j := strings.LastIndex(field, `"`); j >= 0 {        field = field[j+1:]    }}fmt.Println(field) // outputs foobar游乐场链接注意:正如您所看到的,为了能够查找该字段,您需要访问数据,但是当您直接使用json.NewDecoder并传递请求的正文时,而不先将其内容存储在某处,您'一旦解码器的Decode方法完成,将失去对该数据的访问。这是因为主体是封装在io.ReadCloser不支持“倒带”的字节流中,即您无法重新读取解码器已读取的字节。为了避免这种情况,您可以使用ioutil.ReadAll读取正文的完整内容,然后json.Unmarshal进行解码。第二种错误是json.UnmarshalTypeError. 如果您查看错误类型及其字段的文档,您就会知道您需要做的就是键入断言返回的值,然后就完成了。在 json 成功解码为结构后,将对“空白”和“愚蠢”值进行验证。如何做到这一点取决于您。例如,您可以使用专为验证结构而设计的第 3 方包,或者您可以自己实现内部解决方案等。实际上,我对其中哪一个是“最好的”没有意见,所以我可以'帮不了你。我能说的是,最基本的方法是简单地查看结构的每个字段,并根据该字段的要求检查其值是否有效。
随时随地看视频慕课网APP

相关分类

Go
我要回答