Golang创建一个简单的http服务
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| package main
import ( "fmt" "net/http" )
func hello(resp http.ResponseWriter, req *http.Request) { fmt.Fprintf(resp, "hello") }
func main() { // 创建http监听 路径 方法 http.HandleFunc("/", hello) // 配置监听地址 ListenAndServe会一直处于挂起状态 err := http.ListenAndServe("0.0.0.0:8888", nil) if err != nil { fmt.Printf("http err:%s\n", err) } }
|
发送一个Http请求
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| package main
import ( "fmt" "net/http" "net/http/httputil" )
// http client func main() { res, err := http.Get("http://www.baidu.com/") if err != nil { fmt.Println("get err:", err) return } data, err := httputil.DumpResponse(res, true) if err != nil { fmt.Println("get data err:", err) return } fmt.Println(string(data)) }
|
HTTP常见的请求方法:GET、POST、PUT、DELETE、HEAD
发送一个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
| package main
import ( "fmt" "net/http" )
var urls = []string{ "http://www.baidu.com/", "http://www.google.com", "http://www.taobao.com", }
// head 测试url是否能打开 func main() { for _, url := range urls { resp, err := http.Head(url) if err != nil { fmt.Println("request err:", err) continue } fmt.Printf("head %s success,status:%d\n", url, resp.StatusCode) } }
|
HEAD请求如果对应URL长时间没有响应,会触发超时处理
自定义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
| package main
import ( "fmt" "net" "net/http" "time" )
var urls = []string{ "http://www.baidu.com/", "http://www.google.com", "http://www.taobao.com", }
func main() { // 自定义超时时间 c := http.Client{ Transport: &http.Transport{ Dial: func(network, addr string) (conn net.Conn, err error) { timeout := time.Second * 3 return net.DialTimeout(network, addr, timeout) }, }, }
for _, url := range urls { resp, err := c.Head(url) if err != nil { fmt.Println("request err:", err) continue } fmt.Printf("head %s success,status:%d\n", url, resp.StatusCode) } }
|
简单的表单处理:
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
| package main
import ( "fmt" "io" "net/http" )
// 表单处理
func hello(respWrite http.ResponseWriter, req *http.Request) { io.WriteString(respWrite, "hello world ") }
func loginHandle(respWrite http.ResponseWriter, req *http.Request) { var form = `<!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <form action="#" method="POST"> <input type="text" name="username"> <input type="text" name="passwd"> <input type="submit" value="登录"> </form> </body> </html>` respWrite.Header().Set("content-type", "text/html; charset=UTF-8") switch req.Method { case "GET": io.WriteString(respWrite, form) case "POST": req.ParseForm() io.WriteString(respWrite, req.FormValue("username")) io.WriteString(respWrite, "\n") io.WriteString(respWrite, req.FormValue("passwd"))
} }
func main() { http.HandleFunc("/", hello) http.HandleFunc("/login", loginHandle) if err := http.ListenAndServe(":8888", nil); err != nil { fmt.Println("http server start err:", err) } }
|
如果不进行panic处理,某一次请求发生了panic,则会导致整个http服务终止
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
| package main
import ( "fmt" "io" "log" "net/http" )
func loginHandle(respWriter http.ResponseWriter, req *http.Request) { io.WriteString(respWriter, "login") panic("login err")
}
// panic 处理 func logPanicHandle(hand http.HandlerFunc) http.HandlerFunc { return func(respWriter http.ResponseWriter, req *http.Request) {
defer func() { if err := recover(); err != nil { log.Printf("[%v] url:[%v] panic: %v", req.RemoteAddr, req.RequestURI, err) } }()
hand(respWriter, req) } }
func main() { http.HandleFunc("/login", logPanicHandle(loginHandle)) err := http.ListenAndServe(":8888", nil) if err != nil { fmt.Println("server err:", err) } }
|