http介绍
编写web语言:
1.java
2.php,现在都在尝试用go语言编写
3.python,豆瓣
4.go语言 ===》 beego,gin两个主流的web框架
https协议:我们使用浏览器访问的时候发送的就是http请求
- http是应用层的协议,底层还是依赖传输层:tcp(短链路),网络层(ip)
- 无状态的,每一次请求都是独立的,下次请求要重新建立连接
- https:
http是标准协议==》明文传输,不安全
https不是标准协议==》https = http+ssl(非对称加密,数字证书)-》加密的
现在所有网站都会尽量要求https开发:安全
http请求报文格式
一个http请求可以分为4个部分:
1.请求行 2.请求头 3.空行 4.请求包体
http响应消息格式
http响应格式也分为4部分:
- 第一部分:状态行
协议格式:协议版本号 + 状态码 + 状态描述
实例1:HTTP/1.1 + 200 + ok
实例2:HTTP/1.1 + 404 + Page not found
常用的状态码:
1xx -> 客户端可以继续发送请求
2xx-> 正常访问,200
3xx-> 重定向
4xx -> 401(未授权) not authorized 404(not found)
5xx-> Internal Error 服务器内部错误 - 第二部分:响应头
Content-Type:application/json
Server:Apache
Data:Mon,12 Sep… - 第三部分:空行
用于分割,没有响应头了 - 第四部分:响应包体
通常是返回json数据
http响应代码演示
package main import ( "fmt" "net/http" "io/ioutil" ) func main() { //http包 client := http.Client{} // func (c *Client) Get(url string) (resp *Response,err error){ resp,err := client.Get("https://www.baidu.com") if err != nil{ fmt.Println("Client.Get err:",err) return } // 放在上边,内容很多 body := resp.Body fmt.Println("body 111:",body) // func ReadAll(r io.Reader) ([]byte,error){ // } readBodyStr,err := ioutil.ReadAll(body) if err != nil{ fmt.Println("read body err:",err) return } fmt.Println("body string:",string(readBodyStr)) ct := resp.Header.Get("Content.Type") date := resp.Header.Get("Date") server := resp.Header.Get("Server") fmt.Println("content-type:",ct) fmt.Println("date:",date) fmt.Println("server:",server) url := resp.Request.URL code := resp.StatusCode status := resp.Status fmt.Println("url:",url) fmt.Println("code:",code) fmt.Println("status:",status) }
http-server代码实现
package main import ( "net/http" "fmt" "io" ) func main(){ // 注册路由router // xxx/user ===> func1 // xxx/name ===> func2 // xxx/id ===> func3 // https://127.0.0.1:8080/user,func是回调函数,用于路由的响应,这个回调函数原型是固定 http.HandleFunc("/user",func(writer http.ResponseWriter,request *http.Request){ // request :===> 包含客户端发来的数据 fmt.Println("用户请求详情:") fmt.Println("request:",request) // writer :===> 通过writer将数据返回给客户端 _,_ = io.WriteString(writer,"这是/user请求返回的数据!") }) http.HandleFunc("/name",func(writer http.ResponseWriter,request *http.Request){ _,_ = io.WriteString(writer,"这是/name请求返回的数据!") }) http.HandleFunc("/id",func(writer http.ResponseWriter,request *http.Request){ _,_ = io.WriteString(writer,"这是/id请求返回的数据!") }) fmt.Println("Http Server start ...") // func ListenAndServe(addr string,handler Handler) error{ // http.ListenAndServe() if err := http.ListenAndServe("127.0.0.1:8080",nil);err != nil{ fmt.Println("http start failed,err:",err) return } }
JSON编解码案例
package main import ( "fmt" "encoding/json" ) type Student struct{ Id int Name string Age int gender string // 注意:gender是小写的 } func main(){ // 在网络中传输的时候,把Student结构体,编码成json字符串,传输 ===》 结构体 ===》 字符串 ==》 编码 // 接收字符串,需要将字符串转换成结构体,然后操作==》字符串==》结构体==》解密 lily := Student{ Id:1, Name:"Lily", Age:20, gender:"女士", } // 编码(序列化),结构==》字符串 encodeInfo,err := json.Marshal(&lily) if err != nil{ fmt.Println("json.Marshal err:",err) return } fmt.Println("encodeInfo:",string(encodeInfo)) // 对端接收到数据 // 反序列化(解码):字符串=》结构体 var lily2 Student // func Unmarshal(data []byte,v interface{}) error { if err := json.Unmarshal([]byte(encodeInfo),&lily2);err != nil{ fmt.Println("json.Unmarshal err:",err) return } fmt.Println("name:",lily2.Name) fmt.Println("gender:",lily2.gender) fmt.Println("age:",lily2.Age) fmt.Println("id:",lily2.Id) }
注意:由于gender在结构体中首字母是小写开头的,json编码不会参与编码
结构体标签(tag)
package main import ( "encoding/json" "fmt" ) type Teacher struct { Name string `json:"-"` // ==>在使用json编码时,这个编码不参与 Subject string `json:"Subject_name"` // ==> 在json编码时,这个字段会编码成Subject_name Age int `json:"age,string"` // ==>在json编码时,将age转成string类型,一定要两个字段:名字,类型,中间不能有空格 Address string `json:"address,omitempty"` // ==>在json编码时,如果这个字段是空的,那么忽略,不参与编码 // 注意:gender是小写的,小写字母开头的,在json编码时会会忽略掉 gender string } func main(){ t1 := Teacher{ Name:"Duke", Subject:"Golang", Age:18, gender:"Man", Address:"北京", } fmt.Println("t1",t1) encodeInfo,_ := json.Marshal(&t1) fmt.Println("encodeInfo:",string(encodeInfo)) }
总结
1.对于结构体进行编码时(json),字段的首字母必须大写,否则无法编码
2.如果json格式要求key小写,那么可以通过标签(tag)来解决
3. tag细节
Name string `json:"-"` // ==>在使用json编码时,这个编码不参与 Subject string `json:"Subject_name"` // ==> 在json编码时,这个字段会编码成Subject_name Age int `json:"age,string"` // ==>在json编码时,将age转成string类型,一定要两个字段:名字,类型,中间不能有空格
感谢大家观看,我们下次见