net/http使用简析
- 路由:路由注册在http.HandlerFunc(Path,handlerfunc)//接收一个资源定位的路径和一个响应函数
- 响应函数HandlerFunc(http.ResponseWriter,*http.Request)//其中http.Writer是一个接口实现了客户端消息的封装,Request获取客户端请求内容
- 在接收参数时需要手动request.ParseForm()解析参数
- http.ListenAndServe(Addr,handler)//启动服务,handler一般为空
结构解析
-
http.Request是客户端发出的或者服务端收到的相关信息,Request.Body和Request.Header对应请求头和消息内容,获取json数据时应当使用Body
-
http.Response{
Status string // e.g. “200 OK”
StatusCode int // e.g. 200
Proto string // e.g. “HTTP/1.0”
ProtoMajor int // e.g. 1
ProtoMinor int // e.g. 0
…
}Response对应http回复相关信息 -
Request.Form//请求头中的参数
-
Request.ParseForm()//解析URL中的查询字符串,并将解析结果更新到Form字段。
-
http.Client//http客户端
type Client struct {
Transport RoundTripper
CheckRedirect func(req *Request, via []*Request) error
Jar CookieJar
Timeout time.Duration
}
常用方法:对应http中客户端发起的请求
func (c *Client) Head(url string) (resp *Response, err error)
func (c *Client) Get(url string) (resp *Response, err error)
func (c *Client) Post(url string, bodyType string, body io.Reader) (resp *Response, err error)
func (c *Client) PostForm(url string, data url.Values) (resp *Response, err error)
- http.Server
type Server struct {
Addr string
Handler Handler
ReadTimeout time.Duration
WriteTimeout time.Duration
MaxHeaderBytes int
TLSConfig *tls.Config
TLSNextProto map[string]func(*Server, *tls.Conn, Handler)
ConnState func(net.Conn, ConnState)
ErrorLog *log.Logger
}Server中的字段是http服务端的配置信息
func (srv *Server) Serve(l net.Listener) error//监听连接,为每一个加入的连接创建一个协程
func (srv *Server) ListenAndServe() error//监听srv.Addr指定的TCP地址,并且会调用Serve方法接收到的连接。如果srv.Addr为空字符串,会使用":http"。
- http.Header
type Header map[string][]string//http头域键值对
func (h Header) Get(key string) string//返回键对应值
func (h Header) Set(key, value string)//为Header添加键值对,如果存在则以当前值替换原来的值
func (h Header) Add(key, value string)//为Header添加键值对,如果存在则将当前值添加到值序列中
func (h Header) Del(key string)//删除
- Cookie
type Cookie struct {
Name string
Value string
Path string // optional
Domain string // optional
Expires time.Time // optional
RawExpires string // for reading cookies only
// MaxAge=0 means no 'Max-Age' attribute specified.
// MaxAge<0 means delete cookie now, equivalently 'Max-Age: 0'
// MaxAge>0 means Max-Age attribute present and given in seconds
MaxAge int
Secure bool
HttpOnly bool
SameSite SameSite
Raw string
Unparsed []string // Raw text of unparsed attribute-value pairs
}相关函数:
http.SetCookie(w ResponseWriter, cookie *Cookie)//添加一个Set-Cookie头部
func SetCookie(w ResponseWriter, cookie *Cookie) {
if v := cookie.String(); v != "" {
w.Header().Add("Set-Cookie", v)
}
}
Request.Cookie(name string)(*Cookie, error)//获取指定Cookie
Request.Cookies()[]*Cookie获取所有Cookie
Request.AddCookie(c *Cookie)
func (r *Request) AddCookie(c *Cookie) {
s := fmt.Sprintf("%s=%s", sanitizeCookieName(c.Name), sanitizeCookieValue(c.Value))
if c := r.Header.Get("Cookie"); c != "" {
r.Header.Set("Cookie", c+"; "+s)
} else {
r.Header.Set("Cookie", s)
}
}//为请求添加cookie
使用实例:
/*
这是一个登陆功能的实现,程序主要是将客户端发送的json数据在服务端解析,并到Mongodb中查询并返回结果
*/
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
)
func check(err error) {
if err != nil {
log.Println(err)
}
}
type Account struct {
Username string `json:"username" bson:"username"`
Password string `json:"password" bson:"passord"`
Email string `json:"email" bson:"email"`
}
func HomePage(W http.ResponseWriter, Request *http.Request) {
Request.ParseForm()
log.Printf("Request Type of Client:%v", Request.Method)
fmt.Fprint(W, "Homepage")//将需要返回的字段写入W
}
func queryMongoAccount(ch chan bool, user Account) {
cli, err := mgo.Dial(HOST)
defer cli.Close()
check(err)
collection := cli.DB("account").C("account")
res, err2 := collection.Find(bson.M{"username": user.Username, "password": user.Password}).Count() //查询是否有记录匹配
log.Println(bson.M{"username": user.Username, "password": user.Password})
log.Println(user)
check(err2)
if res != 0 {
ch <- true
} else {
ch <- false
}
log.Println(res)
}
func IsAccount(W http.ResponseWriter, Request *http.Request) {
Request.ParseForm()
account := Account{}
mongoMessage := make(chan bool)
body, err := ioutil.ReadAll(Request.Body) //读取POST body
check(err)
json.Unmarshal(body, &account)
if Request.Method == "POST" {
go queryMongoAccount(mongoMessage, account)
flag := <-mongoMessage //true or not
switch flag {
case true:
fmt.Fprint(W, "true") //返回页面
case false:
fmt.Fprint(W, "false")
}
}
}
func StartServer() {
http.HandleFunc("/", HomePage)//路由设置
http.HandleFunc("/IsAccount", IsAccount)
err := http.ListenAndServe(":9090", nil)
check(err)
}
func main() {
StartServer()
}