go中的http包的学习
Go语言通过引入net/http包来实现http网络访问,并提供HTTP客户端和服务端的实现。
http 服务端
先看服务端的实现,几行代码就可以启动1个HTTP服务,还是很简单的。
package main
import (
"fmt"
"net/http"
)
func getHandler(w http.ResponseWriter, r *http.Request){
_, _ = fmt.Fprintf(w, "hello go!")
}
func main(){
//绑定路由
http.HandleFunc("/", getHandler)
//监听端口,开启服务
err := http.ListenAndServe(":9090", nil)
if err != nil{
fmt.Println("ListenAndServe: ", err)
}
}
简单的分析一下这几行代码的意思。
- http.HandleFunc("/", getHandler) 表示绑定路由,URL上 是 / 的请求,都它走 getHandler 方法去执行。
- http.ListenAndServe(":9090", nil) 表示的监听本地的9090端口,并启动服务,第二参数handler 为 nil,表示不传,这个在下面进行分析。
- getHandler 函数,他接受2个参数,固定写法,一个是给客户端返回的Respone,一个是接受请求的Request。
简单的几句代码,就完成了一个HTTP服务,还是很方便的。
go里面路由是得自己手动进行绑定的,而且是强匹配。你没绑定,就访问不了。所以得1个1个进行绑定,这是很痛苦的一件事情。
//绑定路由
http.HandleFunc("/", getHandler1)
http.HandleFunc("/about", getHandler2)
http.HandleFunc("/user/getUserInfo", getHandler3)
http.HandleFunc("/goods/getList", getHandler4)
......
如果你的项目有很多个接口,那就完蛋了。这样写下去得累死不说,而且很难维护,代码的可读性以及整体感觉会很乱。
最关键是没法实现一些很常见的正则的匹配,比如:
http.HandleFunc("/user/{id}", getHandler4)
http.HandleFunc("/user/{id}/name/{name}", getHandler4)
所以,我想想,怎么去搞一套自动匹配路由的机制,和PHP一样方便。先来看一下,第二种启动服务的方式。
func ListenAndServe(addr string, handler Handler) error {}
ListenAndServe 的第一个参数addr,第二个参数类型是Handler。我们看下Handler的定义:
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
他是一个接口。只要实现了接口里面的ServeHTTP的方法的,都可以传入。我们可以利用这个参数,来实现自动化路由:
package main
import (
"fmt"
"net/http"
)
func getHandler(w http.ResponseWriter, r *http.Request){
if r.URL.Path == "/" {
_, _ = fmt.Fprintf(w, "hello go!")
return
}
if r.URL.Path == "/about" {
_, _ = fmt.Fprintf(w, "about go!")
return
}
http.NotFound(w, r)
}
func main(){
//http.HandleFunc("/b", getHandler)
err := http.ListenAndServe(":9090", http.HandlerFunc(getHandler))
if err != nil{
fmt.Println("ListenAndServe: ", err)
}
}
差不多的代码,http.HandlerFunc() 是将一个普调的函数转换成Handler类型的。这样,我们就可以在函数里面通过判断r.URL.Path的方式,来实现自动路由了。
但是这一种效率比第一张直接绑定的效率要低一点。
也可以自定义方法,只要实现ServeHTTP就行:
package webser
import (
"strings"
"fmt"
"net/http"
"log"
)
type MyMux struct{
}
func (p *MyMux)ServeHTTP(w http.ResponseWriter, r *http.Request){
if r.URL.Path == "/"{
sayHelloName(w, r)
return
}
if r.URL.Path == "/about"{
about(w, r)
return
}
http.NotFound(w,r)
return
}
func sayHelloName(w http.ResponseWriter, r *http.Request){
r.ParseForm()
fmt.Println(r.Form)
fmt.Println("path: ", r.URL.Path)
fmt.Println("scheme: ", r.URL.Scheme)
for k, v := range r.Form{
fmt.Println("key: ", k)
fmt.Println("val: "

本文介绍了Go语言中http包的使用,包括服务端的启动,如HandleFunc绑定路由,ListenAndServe监听端口,以及手动路由绑定的不便。接着探讨了通过实现接口自定义路由的方法,提高代码可读性和维护性。客户端部分讲解了GET和POST请求的发送,特别是POST请求中表单和JSON格式的区别。
最低0.47元/天 解锁文章

1341

被折叠的 条评论
为什么被折叠?



