Post

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)
}
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

  1. 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
             }
         }
      
  2. 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))
        }
      

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.