美文网首页
Go Web开发四:处理请求

Go Web开发四:处理请求

作者: 狂奔的胖蜗牛 | 来源:发表于2018-06-26 21:44 被阅读106次

1.HTTP报文结构

HTTP分为请求和响应类型,都具有相同的结构:
1.请求行或者响应行
2.0个或者多个首部
3.一个空行
4.一个可选的报文主体

1.1Request结构

Request结构表示一个客户端发送的HTTP请求报文,该结构包含了报文经过语法分析后较为重要的信息。

组成:
1.URL字段
2.Header字段
3.Body字段
4.Form字段
5.PostForm字段
6.MultipartForm字段

通过该结构,可以对请求报文中的cookie,url代理等进行访问。

1.1.1URL字段

表示请求中包含的URL,该字段是一个指向url.URL结构的指针。定义如下:

type URL struct {
    Scheme     string
    Opaque     string    // encoded opaque data
    User       *Userinfo // username and password information
    Host       string    // host or host:port
    Path       string    // path (relative paths may omit leading slash)
    RawPath    string    // encoded path hint (see EscapedPath method)
    ForceQuery bool      // append a query ('?') even if RawQuery is empty
    RawQuery   string    // encoded query values, without '?'
    Fragment   string    // fragment for references, without '#'
}

1.1.2Header字段

请求和响应的首部都使用Header类型描述。

package main

import (
    "net/http"
    "fmt"
)

func main() {
    server := http.Server{
        Addr: "127.0.0.1:8080",
    }
    http.HandleFunc("/headers", headers)
    server.ListenAndServe()
}

func headers(w http.ResponseWriter, r *http.Request) {
    h := r.Header
    fmt.Fprintln(w, h)
}

代码中的r.Header即把请求首部读取出来,并写入response返回给客户端。

可以使用指定键获得Header中的值,如:

//获得字符串切片
h := r.Header["Accept-Encoding"]
//获得字符串,使用逗号分隔开
h := r.Header.Get("Accept-Encoding")

1.1.3Body字段

请求和响应的主体都由Request结构的Body字段表示,该字段是一个io.ReadCloser接口。

使用Read方法读取主体的内容:

func main() {
    server := http.Server{
        Addr: "localhost:8080",
    }
    http.HandleFunc("/body", body)
    server.ListenAndServe()
}

func body(w http.ResponseWriter, r *http.Request) {
    len := r.ContentLength//获取主体数据的字节长度
    body := make([]byte, len)//根据长度创建出字节数组
    r.Body.Read(body)//将主体数据读取到body中
    fmt.Fprintln(w, string(body))
}

在终端使用cURL命令即可模拟POST请求

yuhua$ curl -id "body" localhost:8080/body

输出如下内容:

HTTP/1.1 200 OK
Date: Mon, 25 Jun 2018 15:12:11 GMT
Content-Length: 5
Content-Type: text/plain; charset=utf-8

body

1.1.4Form字段

通过调用Request提供的方法,用户可以将URL,主体等数据提取到Form,PostForm,MultipartForm等字段中。下面代码调用了ParseForm方法,访问时,就应该访问相应的Form字段。

func main() {
    server := http.Server{
        Addr: "localhost:8080",
    }
    http.HandleFunc("/process", process)
    server.ListenAndServe()
}

func process(w http.ResponseWriter, r *http.Request) {
    r.ParseForm()//对表单进行分析
    fmt.Fprintln(w, r.Form)
}

编写好html文件,用浏览器打开:

<html>
<head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
    <title>GoWeb</title>
</head>
<form action=http://127.0.0.1:8080/process?hello=world&thread=123 method="post" enctype="application/x-www-form-urlencoded">
    <input type="text" name="hello" value="sau"/>
    <input type="text" name="post" value="456"/>
    <input type="submit">
</form>
</html>

点击提交后,得到如下结果:

map[post:[456] hello:[sau world] thread:[123]]

我们发现,使用application/x-www-form-urlencoded格式,最终的Form字段会包含URL与body中的值。

2.ResponseWrite

ResponseWrite是一个接口,处理器通过该接口创建HTTP响应。

该接口有3个方法:
1.Write
2.WriteHeader
3.Header

2.1Write

package main

import "net/http"

func main() {
    server := http.Server{
        Addr: "localhost:8080",
    }
    http.HandleFunc("/write", write)
    server.ListenAndServe()
}

func write(w http.ResponseWriter, r *http.Request) {
    str := `<html><head><title>Go Web</title></head><body><h1>Hello World</h1></body></html>`
    w.Write([]byte(str))
}

浏览器浏览后:


屏幕快照 2018-06-26 下午9.23.24.png

2.2WriteHeader

将状态码写入返回中。如:你定义一个API,但是没有实现,当客户端访问时,可以返回501。

package main

import (
    "net/http"
    "fmt"
)

func main() {
    server := http.Server{
        Addr: "localhost:8080",
    }
    http.HandleFunc("/write", write)
    http.HandleFunc("/writeHeader", writeHeader)
    server.ListenAndServe()
}

func write(w http.ResponseWriter, r *http.Request) {
    str := `<html><head><title>Go Web</title></head><body><h1>Hello World</h1></body></html>`
    w.Write([]byte(str))
}

func writeHeader(w http.ResponseWriter, r *http.Request) {
    w.WriteHeader(501)//该方法只允许设置一次,不允许多次设置
    fmt.Fprintln(w, "没有实现!")
}

访问后:


屏幕快照 2018-06-26 下午9.29.30.png

2.3Header

调用Header方法,可以取得一个由首部组成的映射,修改该映射就可以修改首部,修改后的首部被包含在HTTP响应里,并随着响应一同发送至客户端。

package main

import (
    "net/http"
    "fmt"
)

func main() {
    server := http.Server{
        Addr: "localhost:8080",
    }
    http.HandleFunc("/write", write)
    http.HandleFunc("/writeHeader", writeHeader)
    http.HandleFunc("/header", header)
    server.ListenAndServe()
}

func write(w http.ResponseWriter, r *http.Request) {
    str := `<html><head><title>Go Web</title></head><body><h1>Hello World</h1></body></html>`
    w.Write([]byte(str))
}

func writeHeader(w http.ResponseWriter, r *http.Request) {
    w.WriteHeader(501)
    fmt.Fprintln(w, "没有实现!")
}

func header(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Location", "http://www.baidu.com")
    w.WriteHeader(302)
}

浏览器打开会自动跳转到百度页面。

2.4返回JSON

返回Back结构体JSON。

package main

import (
    "net/http"
    "fmt"
    json2 "encoding/json"
)

func main() {
    server := http.Server{
        Addr: "localhost:8080",
    }
    http.HandleFunc("/write", write)
    http.HandleFunc("/writeHeader", writeHeader)
    http.HandleFunc("/header", header)
    http.HandleFunc("/json", jsonBack)
    server.ListenAndServe()
}

func write(w http.ResponseWriter, r *http.Request) {
    str := `<html><head><title>Go Web</title></head><body><h1>Hello World</h1></body></html>`
    w.Write([]byte(str))
}

func writeHeader(w http.ResponseWriter, r *http.Request) {
    w.WriteHeader(501)
    fmt.Fprintln(w, "没有实现!")
}

func header(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Location", "http://www.baidu.com")
    w.WriteHeader(302)
}

type back struct {
    User string
    Threads []string
}

func jsonBack(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Conten-Type", "application/json")
    back := &back{
        User: "Sau",
        Threads: []string{"first", "second", "third"},
    }
    json, _ :=  json2.Marshal(back)
    w.Write(json)
}

浏览器浏览后返回:


屏幕快照 2018-06-26 下午9.43.11.png

相关文章

网友评论

      本文标题:Go Web开发四:处理请求

      本文链接:https://www.haomeiwen.com/subject/mpmuyftx.html