天天看点

Golang请求数据处理

获取参数

我们经常需要获取用户传递的数据,包括

GET

POST

等方式的请求。你可以通过如下方式获取数据:

通过

r.Form.Get("参数名")

r.PostForm.Get("参数名")

获取对应字段的值,r表示服务器接收或由客户端发送的

HTTP

请求。在Go标准包

net/http

中的

request.go

文件中可以看到该结构体的定义,其中与今天讨论有关的字段有

type Request struct {
	Body 			io.ReadCloser
    Form 			url.Values  
    PostForm 		url.Values
    MultipartForm 	*multipart.Form
}
           

Body

字段后面的这三个字段都需要依赖其他方法,前两者需要调用

ParseForm()

方法,后者需要调用

ParseMultipartForm()

方法。

  • 对于所有的请求,

    ParseForm

    URL

    解析原始查询,对于

    POST

    PUT

    PATCH

    请求,它还会将请求解析为表单,并将结果放入

    r.PostForm

    r.Form

    中。请求

    body

    参数优先于

    r.Form

    中的

    URL

    查询字符串值。

    对于其他

    HTTP

    方法,或者当

    Content-Type

    不是

    application/x-www-form-urlencoded

    时,该方法不会读取请求

    body

    ,同时也不会将

    r.PostForm

    初始化为非零空值。

    如果请求

    body

    的大小没有提前限定,那么它的最大值为

    10MB

  • ParseMultipartForm

    解析表单属性

    enctype

    multipart/form-data

    的内容。

    func (r *Request) ParseMultipartForm(maxMemory int64) error

    ,调用

    ParseMultipartForm

    之后,上传的文件存储在

    maxMemory

    大小的内存里面,如果文件大小超过了

    maxMemory

    ,那么剩下的部分将存储在系统的临时文件中。

直接解析到struct

当请求不能用上面的方法获取时,可以使用

ioutil.ReadAll(r.Body)

读取请求中的

body

。再通过

struct

的字段名或

tag

body

中对应字段直接解析到

struct

。定义

struct

时,字段名后如果有

form

这个

tag

,则会以把

form

表单里的

name

tag

的名称一样的字段赋值给这个字段,否则就会把

form

表单里与字段名一样的表单内容赋值给这个字段。

如果要忽略一个字段,有两种办法:一是字段名小写开头,二是

form

标签的值设置为

-

完整代码

main.go
package main

import (
	"net/http"
	"fmt"
	"io/ioutil"
	"encoding/json"
	"html/template"
)

type Test struct {
	NickName string `json:"nickname"`
	Phone    string `json:"phone"`
	PassWord string `json:"password"`
}

func main() {
	http.HandleFunc("/test", testFunc)
	http.HandleFunc("/testdata", testData)
	http.ListenAndServe(":8000", nil)
}

func testFunc(w http.ResponseWriter, r *http.Request) {
	t, _ := template.ParseFiles("templates/test.html")
	t.Execute(w, nil)
}

func testData(w http.ResponseWriter, r *http.Request) {
	var test Test
	r.ParseForm()
	test.NickName = r.Form.Get("nickname")
	if test.NickName == "" {
		data, err := ioutil.ReadAll(r.Body)
		if err != nil {
			fmt.Println(err)
			return
		}
		err = json.Unmarshal(data, &test)
		if err != nil {
			fmt.Println(err)
			return
		}
		fmt.Fprintf(w, "====>%s %s %s", test.NickName, test.Phone, test.PassWord)
	} else {
		test.Phone = r.Form.Get("phone")
		test.PassWord = r.Form.Get("password")
		fmt.Fprintf(w, "%s %s %s", test.NickName, test.Phone, test.PassWord)
	}
}
           
test.html
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>test</title>
</head>
<body>
<form action="/testdata" method="post">
    NickName:<br>
    <input type="text" name="nickname" value="请输入昵称">
    <br>
    Phone:<br>
    <input type="text" name="phone" value="请输入手机号">
    <br>
    PassWord:<br>
    <input type="text" name="password" value="请输入密码">
    <br><br>
    <input type="submit" value="submit">
</form>
</body>
</html>