Go web Process
Go web Process
Process
Request
http.Request
1
2
3
4
5
6
7
8
9
10
11
// 重要字段
type Request struct {
Method string
URL *url.URL
Header Header
Body io.ReadCloser
Form url.Values
PostForm url.Values
MultipartForm *multipart.Form
}
URL
1
2
3
4
5
6
7
8
9
10
11
12
13
type URL struct {
Scheme string
Opaque string // encoded opaque data
User *Userinfo // username and password information
Host string // host or host:port (see Hostname and Port methods)
Path string // path (relative paths may omit leading slash)
RawPath string // encoded path hint (see EscapedPath method)
OmitHost bool // do not emit empty host (authority)
ForceQuery bool // append a query ('?') even if RawQuery is empty
RawQuery string // encoded query values, without '?'
Fragment string // fragment for references, without '#'
RawFragment string // encoded fragment hint (see EscapedFragment method)
}
Header
1
type Header map[string][]string
Body
1
2
3
4
5
6
7
8
9
10
11
12
type ReadCloser interface {
Reader
Closer
}
type Reader interface {
Read(p []byte) (n int, err error)
}
type Closer interface {
Close() error
}
Form
- Form
- 如果表单和URL中有相同字段, 都会获得, 表单在前, URL在后
- ParseForm解析Request;
- 访问Form字段
- PostForm
- 只会有表单数据
- ParseForm解析Request;
- 访问PostForm字段
- MultipartForm
- 只包含表单数据
- ParseMutilpartForm解析Request;
- 访问MultipartForm字段
1 2 3 4 5 6 7 8 9 10 11
// Form和PostForm只支持application/x-www-form-urlencoded Form url.Values PostForm url.Values type Values map[string][]string // MultipartForm支持multipart/form-data MultipartForm *multipart.Form type Form struct { Value map[string][]string File map[string][]*FileHeader }
上传文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// simple process uploaded file func
func process(w http.ResponseWriter, r *http.Request){
// 假设大小为1024Bytes
r.ParseMultipartForm(1024)
// <input type="file" name="uploaded"> 前端表单, name对应File中的key
// 支持上传多个文件, 通过index取第一个文件
fileHeader := r.MultipartForm.File["uploaded"][0]
file, err := fileHeader.Open()
// 等价于上面三行代码, 自动Parse, 获取第一个文件
// file, fileHeader, err:=r.FormFile("uploaded")
if err == nil{
data, err := io.ReadAll(file)
if err == nil{
fmt.Fprintln(w, string(data))
}
}
}
JSON
tags映射
1
2
3
4
5
type Entity struct{
// `json:""` 方式映射, json指明类型, ""中为json字段中的key
ID int `json:"id"`
// ...
}
类型映射
- Go bool -> JSON boolean
- Go float64 -> JSON 数值
- Go string -> JSON strings
- Go nil -> JSON null
- 对于未知结构的JSON, 使用map[string]interface{}, 存储任意JSON对象
- []interface{}, 存储任意的JSON数组
读取与写入JSON
- decode encode
- 针对Stream, io.Writer/io.Reader
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
func delJSON(w http.ResponseWriter, r *http.Request){ entity:=Entity{} // 读取JSON dec:=json.NewDecoder(r.Body) err:=dec.Decode(&entity) if err!=nil{ // process error return } // 写入JSON enc:=json.NewEncoder(w) err = enc.Encode(entity) if err!=nil{ // process error return } }
- 针对Stream, io.Writer/io.Reader
- Marshal Unmarshal
- 针对string or bytes
1 2 3 4 5 6 7 8 9 10 11 12 13
func delJSON() { entity := Entity{} jsonStr := `{}` // 解码jsonStr到entity中 _ = json.Unmarshal([]byte(jsonStr), &entity) // 写入json bytes, _ := json.Marshal(entity) // 写入json, 带缩进 bytesIndent, _ := json.MarshalIndent(entity, "", " ") fmt.Println(string(bytes)) fmt.Println(string(bytesIndent)) }
- 针对string or bytes
Response
ResponseWriter
- 底层是操作非导出的response
1 2 3 4 5 6
type ResponseWriter interface { Header() Header Write([]byte) (int, error) // 调用WriteHeader后, 无法修改Header WriteHeader(statusCode int) }
- response是实现了ResponseWriter接口的struct
1 2 3 4
type response struct {} func (w *response) Header() Header {} func (w *response) Write(data []byte) (n int, err error) {} func (w *response) WriteHeader(code int) {}
内置Response
- NotFound
- func NotFound(w ResponseWriter, r *Request)
- ServeFile
- 从文件系统提供文件, 返回给请求者
- func ServeFile(w ResponseWriter, r *Request, name string)
- ServeContent
- 把实现了io.ReadSeeker接口的东西的内容返回, 支持只请求资源的一部分内容
- func ServeContent(w ResponseWriter, req *Request, name string, modtime time.Time, content io.ReadSeeker)
- Redirect
- func Redirect(w ResponseWriter, r *Request, url string, code int)
This post is licensed under CC BY 4.0 by the author.