乐趣区

关于go:Go语言WEB框架请求参数处理

获取申请参数

wego 框架中申请参数能够应用一个对立的 Param 对象来获取,Param 对象可获取以下类型的参数:

  • URL 门路参数
    << 门路参数是从 url 的 Path 中匹配的参数,门路参数通常在冒号路由或星号路由中定义,并在 url 申请的 Path 中匹配而获取的。
  • URL 查问参数
    << URL 查问参数,是 URL 申请中以? 为终点的形如 k1=v1&k2=v2… 这样的字符串解析所得的参数。
  • Form 参数
    << Form 参数又称作表单参数,这里的表单数据指的是浏览器将表单数据通过 POST 申请提交给服务器由服务器解析出的数据。
    < 浏览器将发送 POST 申请时的 Content-Type 通常为 x -www-form-urlencoded 或者是 multipart/form-data。

在 wego 中通过 c.Param.GetXXX 函数来获取申请参数:

func TestGetParam(t *testing.T) {web, _ := NewWeb()

   web.GET("/user", func(c *WebContext) {name := c.Param.GetString("name")
       if name.Error != nil {t.Error(name.Error)
       }

       age := c.Param.GetInt("age")
       if age.Error != nil {t.Error(age.Error)
       }

       c.WriteText(200, name.Value)
   })

   w := httptest.NewRecorder()
   req, _ := http.NewRequest("GET", "/user?name=lisi&age=12", nil)
   web.ServeHTTP(w, req)
}

为了不便获取各种类型的参数,wego 提供了一些列 GetXXX 函数用于参数的获取:

  • GetString(key string, defaultValue …string) ValidString
  • GetBool(key string, defaultValue …bool) ValidBool
  • GetInt(key string, defaultValue …int) ValidInt
  • GetInt32(key string, defaultValue …int32) ValidInt32
  • GetInt64(key string, defaultValue …int64) ValidInt64
  • GetFloat(key string, defaultValue …float64) ValidFloat
  • GetTime(key string, format string, defaultValue …time.Time) ValidTime

GetXXX 函数没有间接返回 XXX 类型的值,例如 GetInt 返回的不是 int 类型的值,而是一个 ValidInt 的类型的值:

type ValidInt struct {
   Value     int
   Error      error
}

其中的 Value 参数的值,Error 通常为不存在该参数谬误,或者是类型转换谬误。例如在应用 GetInt(key) 来查问一个参数时,若不存在指定的参数,或者时参数不能转换为 int 类型,则 ValidInt 的 Value 的值为 0,并且会将错误信息赋值给 ValidInt 的 Error 字段。

应用 MustXXX 便捷函数

MustXXX 函数间接返回对应类型的值,应用起来更加便捷。在应用 MustXXX 函数查问参数时,若不存在指定的参数,或者是类型转换谬误,并且在调用时提供了缺省值,则返回缺省值,否则返回对应类型的 ”0″ 值:

  • MustString(key string, defaultValue …string) string
  • MustBool(key string, defaultValue …bool) bool
  • MustInt(key string, defaultValue …int) int
  • MustInt32(key string, defaultValue …int32) int32
  • MustInt64(key string, defaultValue …int64) int64
  • MustFloat(key string, defaultValue …float64) float64
  • MustTime(key string, format string, defaultValue …time.Time) time.Time

    func TestParamMust(t *testing.T) {web, _ := NewWeb()
    
     web.GET("/user", func(c *WebContext) {name := c.Param.MustString("name")
         t.Log(name)
         age := c.Param.MustInt("age")
         t.Log(age)
     })
    
     w := httptest.NewRecorder()
     req, _ := http.NewRequest("GET", "/user?name=lisi&age=12", nil)
     web.ServeHTTP(w, req)
    }

获取门路参数

在 wego 中可通过 WebContext.RouteParam.GetXXX 来获取门路参数:

func TestGetPathParam(t *testing.T) {web, _ := NewWeb()

   web.GET("/hello/:id", func(c *WebContext) {ret := c.RouteParam.GetString("id")
       if ret.Error != nil {t.Error(ret.Error)
       }
       t.Log(ret.Value)
   })

   w := httptest.NewRecorder()
   req, _ := http.NewRequest("GET", "/hello/123", nil)
   web.ServeHTTP(w, req)
}

获取查问参数

在 wego 中通过 WebContext.QueryParam.GetXXX 来获取 URL 查问参数:

func TestGetQueryParamGet(t *testing.T) {web, _ := NewWeb()

   web.GET("/user", func(c *WebContext) {name := c.QueryParam.GetString("name").Value
       age := c.QueryParam.GetInt("age").Value
       t.Log(name)
       t.Log(age)
   })

   w := httptest.NewRecorder()
   req, _ := http.NewRequest("GET", "/user?name=lisi&age=12", nil)
   web.ServeHTTP(w, req)
}

获取 Form 参数

在 wego 中 WebContext.FormParam.GetXXX 来获取 Form 参数:

func TestGetFromParamGet(t *testing.T) {web, _ := NewWeb()

   web.POST("/user", func(c *WebContext) {name := c.FormParam.GetString("name").Value
       age := c.FormParam.GetInt("age").Value
       t.Log(name)
       t.Log(age)
   })

   var buff bytes.Buffer
   buff.WriteString("name=lisi&age=12")

   w := httptest.NewRecorder()
   req, _ := http.NewRequest("POST", "/user", &buff)
   req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
   web.ServeHTTP(w, req)
}

绑定参数到 Struct

除了下面所列的参数获取形式,wego 还提供了参数绑定的形式来获取参数:应用 GetStruct 办法将 HTTP 申请参数间接绑定到 struct 对象。GetStruct 函数会依据 struct 的字段名称或者是字段的 tag 名称来获取申请参数的值。例如:

  • 首先定义 struct

    type FormUser struct {
      Name     string         `form:"name"`
      Age     int
    }
  • 定义好了 FormUser 后,您能够这样来获取表单参数:

    func TestGetStruct(t *testing.T) {web, _ := NewWeb()
    
     web.POST("/user", func(c *WebContext) {
         var user FormUser
         err := c.Param.GetStruct(&user)
         if err != nil {t.Log(err)
         }
         t.Log(user)
     })
    
     var buff bytes.Buffer
     buff.WriteString("name=lisi&Age=12")
    
     w := httptest.NewRecorder()
     req, _ := http.NewRequest("POST", "/user", &buff)
     req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
     web.ServeHTTP(w, req)
    }

解析 Json 格局的 Body 到 Struct

若 POST 申请中 Body 的数据的格局为 JSON 格局,能够间接应用 ReadJSON() 函数来读取:

func TestReadJson(t *testing.T) {web, _ := NewWeb()

    web.POST("/user", func(c *WebContext) {
        var user2 User
        err := c.ReadJSON(&user2)
        if err != nil {t.Log(err)
        }
        t.Log(user2)
    })

    user := User{}
    user.ID = 1
    user.Name = "demo"
    user.Age = 12
    data, _ := json.Marshal(user)

    w := httptest.NewRecorder()
    req, _ := http.NewRequest("POST", "/user",  bytes.NewBuffer(data))
    req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
    web.ServeHTTP(w, req)
}

解析 XML 格局的 Body 到 Struct

若 POST 申请中 Body 的数据的格局为 XML 格局,能够间接应用 ReadXML 函数来读取:

func TestReadXML(t *testing.T) {web, _ := NewWeb()

   web.POST("/user", func(c *WebContext) {
       var user2 User
       err := c.ReadXML(&user2)
       if err != nil {t.Log(err)
       }
       t.Log(user2)
   })

   user := User{}
   user.ID = 1
   user.Name = "demo"
   user.Age = 12
   data, _ := xml.Marshal(user)

   w := httptest.NewRecorder()
   req, _ := http.NewRequest("POST", "/user",  bytes.NewBuffer(data))
   req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
   web.ServeHTTP(w, req)
}

上传文件解决

wego 框架提供了两个很不便的函数来解决上传文件:

  • GetFile(name string) (*multipart.FileHeader, error)

     用于读取表单中的文件信息 
  • SaveToFile(fromfile, tofile string) error

     用于实现疾速保留文件到本地门路 

    示例代码:

    <html lang="en">
    <head>
      <meta charset="utf-8">
      <title>file upload</title>
    </head>
    <body>
    <h1> 上传文件 </h1>
    <form action="/upload" method="post" enctype="multipart/form-data">
      文件: <input type="file" name="file"><br><br>
      <input type="submit" value="上传文件">
    </form>
    </body>
    </html>
  • 服务端代码

    func upload(c *wego.WebContext) {fh, err := c.GetFile("file")
      if err != nil {log.Error(err)
          c.AbortWithError(500, err)
          return
      }
    
      file, err := fh.Open()
      if err != nil {log.Error(err)
          c.AbortWithError(500, err)
          return
      }
      defer file.Close()
    
      data, err := ioutil.ReadAll(file)
      if err != nil {log.Error(err)
          c.AbortWithError(500, err)
          return
      }
    
      c.WriteText(200, string(data))
    }

获取 wego

go get github.com/haming123/wego

退出移动版