gin框架中間件的使用之Next()和Abort()

一、 Next()Abort() 的含義

  1. Next() 的含義

    語法:

    func (c *Context) Next()
    

    英文原文

    Next should be used only inside middleware. It executes the pending handlers in the chain inside the calling handler. 
    

    大意:Next 應該僅可以在中間件中使用,它在調用的函數中的鏈中執行掛起的函數。

  2. Abort() 的含義

    語法:

    func (c *Context)Abort()
    

    英文原文

    Abort prevents pending handlers from being called. Note that this will not stop the current handler. Let's say you have an authorization middleware that validates that the current request is authorized. If the authorization fails (ex: the password does not match), call Abort to ensure the remaining handlers for this request are not called.
    

    大意:Abort 在被調用的函數中阻止掛起函數。注意這將不會停止當前的函數。例如,你有一個驗證當前的請求是否是認證過的 Authorization 中間件。如果驗證失敗(例如,密碼不匹配),調用 Abort 以確保這個請求的其他函數不會被調用。

二、示例分析

func main(){
  router := gin.Default()
  router.Use(middleware.FirstMiddleware(), middleware.SecondMiddleware()) // (1)
  router.Run()
}

func FirstMiddleware() gin.HandlerFunc {
    return func( c *gin.Context) {
        fmt.Println("first middleware before next()")
        isAbort := c.Query("isAbort")
        bAbort, err := strconv.ParseBool(isAbort)
        if err != nil { 
            fmt.Printf("is abort value err, value %s\n", isAbort)
          	c.Next() // (2)
        }
        if bAbort {
            fmt.Println("first middleware abort") //(3)
            c.Abort()
            //c.AbortWithStatusJSON(http.StatusOK, "abort is true")
            return
        } else {
        		fmt.Println("first middleware doesnot abort") //(4)
          	return
        }

        fmt.Println("first middleware after next()")
    }
}

func SecondMiddleware() gin.HandlerFunc {
    return func(c *gin.Context) {
        fmt.Println("current inside of second middleware")
    }
}
  1. 在調用時傳遞的 isAbort() 的值不能解析爲布爾類型的值時,會執行到 (2) 處。此時調用的是 Next() 方法。由第一部分的內容可知。它執行掛起的函數,即在 (1) 處指定的函數,即 SecondMiddleware(),最後執行真正的業務處理函數,程序打印:

    first middleware before next()
    is abort value err, value d
    current inside of second middleware
    inner hello
    first middleware after next()
    

    由上面的打印可知,程序在執行完業務處理後仍然會回到當前的函數。然後打印其他的內容。在使用的過程中,可以根據其餘部分是否繼續執行而在 c.Next() 後添加 return 語句。

  2. 在調用時傳遞的 isAbort() 的值如果是可以解析爲布爾類型的值時,如果值爲真,則執行到 (3) 處。由於此處調用了 Abort() ,根據第一部分的內容可知,它阻止了鏈中後續的函數的調用。所以 SecondMiddleware 函數和業務函數 Hello() 函數不會被調用。但它不能停止當前的函數,故其下面的打印仍會打印

    first middleware before next()
    first middleware abort
    first middleware after next()
    

    注意: Abort()AbortWithStatusJSON` 一直都是中止鏈的調用,不同之處在於,前者不會返回給前端任何內容,而後者則可以返回給前端一個JSON串。

  3. 在調用時傳遞的 isAbort() 的值可以解析爲布爾類型,如果值爲假,則流程會進入到 (4)處。它只是在當前的函數調用中返回,不會對整個鏈造成影響。

    first middleware before next()
    first middleware doesnot abort
    current inside of second middleware
    inner hello
    

參考鏈接:
[1] Failed to Abort() context - gin

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章