Go语言系列(十)- http编程和mysql

释放双眼,带上耳机,听听看~!

http编程

一、Http协议

** 1. 什么是协议?**

协议,是指通信的双方,在通信流程或内容格式上,共同遵守的标准。

** 2. 什么是http协议?**

http协议,是互联网中最常见的网络通信标准。

** 3. http协议的特点**

①通信流程:断开式(无状态)

断开式:http协议每次响应完成后,会断开与客户端的连接

无状态:由于服务器断开了之前的连接,就无法知晓连接间的关系

②内容格式:消息头和消息体

二、http编程概述

   HTTP(HyperText Transfer Protocol,超文本传输协议)是互联网上应用最为广泛的一种网络协议,定义了客户端和服务端之间请求和响应的传输标准。Go语言标准库内建提供了net/http包,涵盖了HTTP客户端和服务端的具体实现。使用net/http包,我们可以很方便地编写HTTP客户端或服务端的程序。

 特点:

  • a. Go原生支持http,import(“net/http”)

  • b. Go的http服务性能和nginx比较接近

  • c. 几行代码就可以实现一个web服务

三、客户端与服务端

  1. 服务端


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
1package main
2
3import (
4    "fmt"
5    "net/http"
6)
7
8//w, 给客户端回复数据
9//r, 读取客户端发送的数据
10func HandConn(w http.ResponseWriter, r *http.Request) {
11    fmt.Println("r.Method = ", r.Method)
12    fmt.Println("r.URL = ", r.URL)
13    fmt.Println("r.Header = ", r.Header)
14    fmt.Println("r.Body = ", r.Body)
15
16    w.Write([]byte("hello go")) //给客户端回复数据
17}
18
19func main() {
20    //注册处理函数,用户连接,自动调用指定的处理函数
21    http.HandleFunc("/", HandConn)
22
23    //监听绑定
24    http.ListenAndServe(":8000", nil)
25}
26

Go语言系列(十)- http编程和mysqlGo语言系列(十)- http编程和mysql


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
1package main
2
3import (
4    "fmt"
5    "net/http"
6)
7
8func Hello(w http.ResponseWriter, r *http.Request) {
9    fmt.Println("r.Method = ", r.Method)
10    fmt.Println("r.URL = ", r.URL)
11    fmt.Println("r.Header = ", r.Header)
12    fmt.Println("r.Body = ", r.Body)
13    fmt.Println("handle hello")
14    fmt.Fprintf(w, "hello ")
15}
16
17func login(w http.ResponseWriter, r *http.Request) {
18    fmt.Println("handle login")
19    fmt.Fprintf(w, "login ")
20}
21
22func history(w http.ResponseWriter, r *http.Request) {
23    fmt.Println("handle history")
24    fmt.Fprintf(w, "history ")
25}
26
27func main() {
28    http.HandleFunc("/", Hello)
29    http.HandleFunc("/user/login", login)
30    http.HandleFunc("/user/history", history)
31    err := http.ListenAndServe("0.0.0.0:8880", nil)
32    if err != nil {
33        fmt.Println("http listen failed")
34    }
35}
36

http_server.go

2. 客户端


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
1package main
2
3import (
4    "fmt"
5    "net/http"
6)
7
8func main() {
9    //resp, err := http.Get("http://www.baidu.com")
10    resp, err := http.Get("http://127.0.0.1:8000")
11    if err != nil {
12        fmt.Println("http.Get err = ", err)
13        return
14    }
15
16    defer resp.Body.Close()
17
18    fmt.Println("Status = ", resp.Status)
19    fmt.Println("StatusCode = ", resp.StatusCode)
20    fmt.Println("Header = ", resp.Header)
21    //fmt.Println("Body = ", resp.Body)
22
23    buf := make([]byte, 4*1024)
24    var tmp string
25
26    for {
27        n, err := resp.Body.Read(buf)
28        if n == 0 {
29            fmt.Println("read err = ", err)
30            break
31        }
32        tmp += string(buf[:n])
33    }
34
35    //读取网页内容,打印出来
36    fmt.Println("tmp = ", tmp)
37}
38

Go语言系列(十)- http编程和mysqlGo语言系列(十)- http编程和mysql


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
1package main
2
3import (
4    "fmt"
5    "io/ioutil"
6    "net/http"
7)
8
9func main() {
10    res, err := http.Get("https://www.baidu.com/")
11    if err != nil {
12        fmt.Println("get err:", err)
13        return
14    }
15
16    data, err := ioutil.ReadAll(res.Body)
17    if err != nil {
18        fmt.Println("get data err:", err)
19        return
20    }
21
22    fmt.Println(string(data))
23}
24

http_client.go

四、http常见请求方法

HTTP请求的方法:

HTTP/1.1协议中共定义了八种方法(有时也叫“动作”),来表明Request-URL指定的资源不同的操作方式

  • 1、OPTIONS


1
2
1返回服务器针对特定资源所支持的HTTP请求方法,也可以利用向web服务器发送‘*’的请求来测试服务器的功能性
2
  • 2、HEAD


1
2
1向服务器索与GET请求相一致的响应,只不过响应体将不会被返回。这一方法可以再不必传输整个响应内容的情况下,就可以获取包含在响应小消息头中的元信息。
2
  • 3、GET


1
2
1向特定的资源发出请求。它本质就是发送一个请求来取得服务器上的某一资源。资源通过一组HTTP头和呈现数据(如HTML文本,或者图片或者视频等)返回给客户端。GET请求中,永远不会包含呈现数据。
2
  • 4、POST


1
2
1向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。 Loadrunner中对应POST请求函数:web_submit_data,web_submit_form
2
  • 5、PUT


1
2
1向指定资源位置上传其最新内容
2
  • 6、DELETE


1
2
1请求服务器删除Request-URL所标识的资源
2
  • 7、TRACE


1
2
1回显服务器收到的请求,主要用于测试或诊断
2
  • 8、CONNECT


1
2
1HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。
2

注意:

  • 1)方法名称是区分大小写的,当某个请求所针对的资源不支持对应的请求方法的时候,服务器应当返回状态码405(Mothod Not Allowed);当服务器不认识或者不支持对应的请求方法时,应返回状态码501(Not Implemented)。
  • 2)HTTP服务器至少应该实现GET和HEAD/POST方法,其他方法都是可选的,此外除上述方法,特定的HTTP服务器支持扩展自定义的方法。

Go语言系列(十)- http编程和mysqlGo语言系列(十)- http编程和mysql


1
2
3
4
5
6
7
8
9
1http.StatusContinue = 100
2http.StatusOK = 200
3http.StatusFound = 302
4http.StatusBadRequest = 400
5http.StatusUnauthorized = 401
6http.StatusForbidden = 403
7http.StatusNotFound = 404
8http.StatusInternalServerError = 500
9

常见状态码

get 和 post区别

区别:

get请求无消息体,只能携带少量数据

post请求有消息体,可以携带大量数据

携带数据的方式:

get请求将数据放在url地址中

post请求将数据放在消息体中

GET请求请提交的数据放置在HTTP请求协议头中,而POST提交的数据则放在实体数据中; 
GET方式提交的数据最多只能有1024字节,而POST则没有此限制。 

五、Head请求


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
1package main
2
3import (
4   "fmt"
5   "net/http"
6   "net"
7   "time"
8)
9
10var url = []string{
11  "http://www.baidu.com",
12  "http://google.com",
13  "http://taobao.com",
14}
15
16func main() {
17
18  for _, v := range url {
19      c := http.Client{
20          Transport: &http.Transport {
21              Dial:func(network, addr string) (net.Conn, error){
22                  timeout := time.Second*2
23                  return net.DialTimeout(network, addr, timeout)
24              },
25          },
26      }
27      resp, err := c.Head(v)
28      if err != nil {
29          fmt.Printf("head %s failed, err:%v\n", v, err)
30          continue
31      }
32
33      fmt.Printf("head succ, status:%v\n", resp.Status)
34  }
35}
36

六、表单及panic处理


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
1package main
2
3import (
4   "io"
5   "log"
6   "net/http"
7)
8
9const form = `<html><body><form action="#" method="post" name="bar">
10                    <input type="text" name="in"/>
11                    <input type="text" name="in"/>
12                     <input type="submit" value="Submit"/>
13             </form></body></html>`
14
15func SimpleServer(w http.ResponseWriter, request *http.Request) {
16  io.WriteString(w, "<h1>hello, world</h1>")
17  panic("test test")
18}
19
20func FormServer(w http.ResponseWriter, request *http.Request) {
21  w.Header().Set("Content-Type", "text/html")
22  switch request.Method {
23  case "GET":
24      io.WriteString(w, form)
25  case "POST":
26      request.ParseForm()
27      io.WriteString(w, request.Form["in"][1])
28      io.WriteString(w, "\n")
29      io.WriteString(w, request.FormValue("in"))
30  }
31}
32func main() {
33  http.HandleFunc("/test1", logPanics(SimpleServer))
34  http.HandleFunc("/test2", logPanics(FormServer))
35  if err := http.ListenAndServe(":8088", nil); err != nil {
36  }
37}
38
39func logPanics(handle http.HandlerFunc) http.HandlerFunc {
40  return func(writer http.ResponseWriter, request *http.Request) {
41      defer func() {
42          if x := recover(); x != nil {
43              log.Printf("[%v] caught panic: %v", request.RemoteAddr, x)
44          }
45      }()
46      handle(writer, request)
47  }
48}
49

七、模板

1. 替换 {{.字段名}}

  • if 判断
  • if 常见操作
  • {{.}}
  • {{with .Var}}… {{end}}

2. 循环

{{range.}}… {{end}}

模板示例1:

Go语言系列(十)- http编程和mysqlGo语言系列(十)- http编程和mysql


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
1package main
2
3import (
4    "fmt"
5    "os"
6    "text/template"
7)
8
9type Person struct {
10    Name  string
11    Title string
12    age   string
13}
14
15func main() {
16    t, err := template.ParseFiles("day10/template/index.html")
17    if err != nil {
18        fmt.Println("parse file err:", err)
19        return
20    }
21    p := Person{Name: "Mary", age: "31", Title: "我的个人网站"}
22    if err := t.Execute(os.Stdout, p); err != nil {
23        fmt.Println("There was an error:", err.Error())
24    }
25}
26

main.go

Go语言系列(十)- http编程和mysqlGo语言系列(十)- http编程和mysql


1
2
3
4
5
6
7
8
9
10
1<html>
2    <head>
3        <title>{{.Title}}</title>
4    </head>
5    <body>
6        <p> hello, {{.Name}}</p>
7        <p> {{.}}</p>
8    </body>
9 </html>
10

index.html


1
2
3
4
5
6
7
8
9
10
1<html>
2    <head>
3        <title>我的个人网站</title>
4    </head>
5    <body>
6        <p> hello, Mary</p>
7        <p> {Mary 我的个人网站 31}</p>
8    </body>
9</html>
10

1
2
1模板示例2
2

Go语言系列(十)- http编程和mysqlGo语言系列(十)- http编程和mysql


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
1package main
2
3import (
4    "fmt"
5    "html/template"
6    "io"
7    "net/http"
8)
9
10var myTemplate *template.Template
11
12type Result struct {
13    output string
14}
15
16func (p *Result) Write(b []byte) (n int, err error) {
17    fmt.Println("called by template")
18    p.output += string(b)
19    return len(b), nil
20}
21
22type Person struct {
23    Name  string
24    Title string
25    Age   int
26}
27
28func userInfo(w http.ResponseWriter, r *http.Request) {
29    fmt.Println("handle hello")
30    //fmt.Fprintf(w, "hello ")
31    var arr []Person
32    p := Person{Name: "Mary001", Age: 10, Title: "我的个人网站"}
33    p1 := Person{Name: "Mary002", Age: 10, Title: "我的个人网站"}
34    p2 := Person{Name: "Mary003", Age: 10, Title: "我的个人网站"}
35    arr = append(arr, p)
36    arr = append(arr, p1)
37    arr = append(arr, p2)
38
39    resultWriter := &Result{}
40    io.WriteString(resultWriter, "hello world")
41    err := myTemplate.Execute(w, arr)
42    if err != nil {
43        fmt.Println(err)
44    }
45    fmt.Println("template render data:", resultWriter.output)
46    //myTemplate.Execute(w, p)
47    //myTemplate.Execute(os.Stdout, p)
48    //file, err := os.OpenFile("C:/test.log", os.O_CREATE|os.O_WRONLY, 0755)
49    //if err != nil {
50    //    fmt.Println("open failed err:", err)
51    //    return
52    //}
53
54}
55
56func initTemplate(filename string) (err error) {
57    myTemplate, err = template.ParseFiles(filename)
58    if err != nil {
59        fmt.Println("parse file err:", err)
60        return
61    }
62    return
63}
64
65func main() {
66    initTemplate("day10/template_http/index.html")
67    http.HandleFunc("/user/info", userInfo)
68    err := http.ListenAndServe("0.0.0.0:8880", nil)
69    if err != nil {
70        fmt.Println("http listen failed")
71    }
72}
73

main.go

Go语言系列(十)- http编程和mysqlGo语言系列(十)- http编程和mysql


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1<html>
2    <head>
3    </head>
4    <body>
5        <p>hello world</p>
6        <table border="1">
7        {{range .}}
8            <tr>
9                <td>{{.Name}}</td> <td>{{.Age}}</td><td>{{.Title}}</td>
10            </tr>
11         {{end}}
12        </table>
13    </body>
14</html>
15

index.html

Go语言系列(十)- http编程和mysql

 

Mysql编程

新建测试表


1
2
3
4
5
6
7
8
9
10
11
12
13
1CREATE TABLE person (
2    user_id int primary key auto_increment,
3    username varchar(260),
4    sex varchar(260),
5    email varchar(260)
6);
7
8CREATE TABLE place (
9    country varchar(200),
10    city varchar(200),
11    telcode int
12)
13

1. 连接mysql


1
2
1database, err := sqlx.Open("mysql", "root:@tcp(127.0.0.1:3306)/test")
2

2. insert操作


1
2
1r, err := Db.Exec("insert into person(username, sex, email)values(?, ?, ?)", "stu001", "man", "stu01@qq.com")
2

Go语言系列(十)- http编程和mysqlGo语言系列(十)- http编程和mysql


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
1package main
2
3import (
4    "fmt"
5
6    _ "github.com/go-sql-driver/mysql"
7    "github.com/jmoiron/sqlx"
8)
9
10type Person struct {
11    UserId   int    `db:"user_id"`
12    Username string `db:"username"`
13    Sex      string `db:"sex"`
14    Email    string `db:"email"`
15}
16
17type Place struct {
18    Country string `db:"country"`
19    City    string `db:"city"`
20    TelCode int    `db:"telcode"`
21}
22
23var Db *sqlx.DB
24
25func init() {
26    database, err := sqlx.Open("mysql", "root:0000@tcp(127.0.0.1:3306)/test")
27    if err != nil {
28        fmt.Println("open mysql failed,", err)
29        return
30    }
31    Db = database
32}
33
34func main() {
35    r, err := Db.Exec("insert into person(username, sex, email)values(?, ?, ?)", "stu001", "man", "stu01@qq.com")
36    if err != nil {
37        fmt.Println("exec failed, ", err)
38        return
39    }
40    id, err := r.LastInsertId()
41    if err != nil {
42        fmt.Println("exec failed, ", err)
43        return
44    }
45
46    fmt.Println("insert succ:", id)
47}
48

mysql_insert

3. select操作


1
2
1err := Db.Select(&person, "select user_id, username, sex, email from person where user_id=?", 1)
2

Go语言系列(十)- http编程和mysqlGo语言系列(十)- http编程和mysql


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
1package main
2
3import (
4    "fmt"
5
6    _ "github.com/go-sql-driver/mysql"
7    "github.com/jmoiron/sqlx"
8)
9
10type Person struct {
11    UserId   int    `db:"user_id"`
12    Username string `db:"username"`
13    Sex      string `db:"sex"`
14    Email    string `db:"email"`
15}
16
17type Place struct {
18    Country string `db:"country"`
19    City    string `db:"city"`
20    TelCode int    `db:"telcode"`
21}
22
23var Db *sqlx.DB
24
25func init() {
26
27    database, err := sqlx.Open("mysql", "root:0000@tcp(127.0.0.1:3306)/test")
28    if err != nil {
29        fmt.Println("open mysql failed,", err)
30        return
31    }
32
33    Db = database
34}
35
36func main() {
37
38    var person []Person
39    err := Db.Select(&person, "select user_id, username, sex, email from person where user_id=?", 1)
40    if err != nil {
41        fmt.Println("exec failed, ", err)
42        return
43    }
44
45    fmt.Println("select succ:", person)
46}
47

mysql_select

4. update操作


1
2
1_, err := Db.Exec("update person set username=? where user_id=?", "stu0001", 1)
2

Go语言系列(十)- http编程和mysqlGo语言系列(十)- http编程和mysql


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
1package main
2
3import (
4    "fmt"
5
6    _ "github.com/go-sql-driver/mysql"
7    "github.com/jmoiron/sqlx"
8)
9
10type Person struct {
11    UserId   int    `db:"user_id"`
12    Username string `db:"username"`
13    Sex      string `db:"sex"`
14    Email    string `db:"email"`
15}
16
17type Place struct {
18    Country string `db:"country"`
19    City    string `db:"city"`
20    TelCode int    `db:"telcode"`
21}
22
23var Db *sqlx.DB
24
25func init() {
26
27    database, err := sqlx.Open("mysql", "root:0000@tcp(127.0.0.1:3306)/test")
28    if err != nil {
29        fmt.Println("open mysql failed,", err)
30        return
31    }
32
33    Db = database
34}
35
36func main() {
37
38    _, err := Db.Exec("update person set username=? where user_id=?", "stu0003", 1)
39    if err != nil {
40        fmt.Println("exec failed, ", err)
41        return
42    }
43
44}
45

mysql_update

5. delete操作


1
2
1_, err := Db.Exec("delete from person where user_id=?", 1)
2

Go语言系列(十)- http编程和mysqlGo语言系列(十)- http编程和mysql


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
1package main
2
3import (
4    "fmt"
5
6    _ "github.com/go-sql-driver/mysql"
7    "github.com/jmoiron/sqlx"
8)
9
10type Person struct {
11    UserId   int    `db:"user_id"`
12    Username string `db:"username"`
13    Sex      string `db:"sex"`
14    Email    string `db:"email"`
15}
16
17type Place struct {
18    Country string `db:"country"`
19    City    string `db:"city"`
20    TelCode int    `db:"telcode"`
21}
22
23var Db *sqlx.DB
24
25func init() {
26
27    database, err := sqlx.Open("mysql", "root:0000@tcp(127.0.0.1:3306)/test")
28    if err != nil {
29        fmt.Println("open mysql failed,", err)
30        return
31    }
32
33    Db = database
34}
35
36func main() {
37
38    _, err := Db.Exec("delete from person where user_id=?", 1)
39    if err != nil {
40        fmt.Println("exec failed, ", err)
41        return
42    }
43
44    fmt.Println("delete succ")
45}
46

mysql_delete

 

给TA打赏
共{{data.count}}人
人已打赏
安全技术

C++异常

2022-1-11 12:36:11

安全技术

Spring Boot 的 10 个核心模块

2022-1-12 12:36:11

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索