成功最有效的方法就是向有经验的人学习!

golang之net-http简单介绍

net-http

介绍

.
├── ClientGet
│ └── main.go // 发送get请求
├── ClientPost
│ └── main.go // 发送post请求
├── Server
│ └── main.go // web服务

Go语言内置的net/http包十分的优秀,提供了HTTP客户端和服务端的实现。

web服务

Server/main.go
客户端 请求信息 封装在 http.Request 对象中
服务端返回的响应报文会被保存在http.Response结构体中
发送给客户端响应的并不是http.Response,而是通过http.ResponseWriter接口来实现的

方法签名 描述
Header() 用户设置或获取响应头信息
Write() 用于写入数据到响应体
WriteHeader() 用于设置响应状态码,若不调用则默认状态码为200 OK。
package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    "net/http"
)

type Data struct {
    Name string `json:"name"`
}

// 处理GET请求: http://127.0.0.1:8005/req/get?name=root
func dealGetRequestHandler(w http.ResponseWriter, r *http.Request) {
    // 获取请求的参数
    query := r.URL.Query()
    if len(query["name"]) > 0 {
        // 方式1:通过字典下标取值
        name := query["name"][0]
        fmt.Println("通过字典下标获取:", name)
    }
    // 方式2:使用Get方法,,如果没有值会返回空字符串
    name2 := query.Get("name")
    fmt.Println("通过get方式获取:", name2)
    type data struct{ Name2 string }
    d := data{Name2: name2}
    //w.Write([]byte(string(d))) // 返回string
    json.NewEncoder(w).Encode(d) // 返回json数据
}

// 处理POST请求: http://127.0.0.1:8005/req/post {"name": "root"}
func dealPostRequestHandler(w http.ResponseWriter, r *http.Request) {
    // 请求体数据
    bodyContent, _ := ioutil.ReadAll(r.Body)
    strData := string(bodyContent)
    var d Data
    json.Unmarshal([]byte(strData), &d) // gin.ShouldBind
    fmt.Printf("body content:[%s]\n", string(bodyContent))
    //返回响应内容
    json.NewEncoder(w).Encode(fmt.Sprintf("收到名字:%s", d.Name))
}
func main() {
    http.HandleFunc("/req/post", dealPostRequestHandler)
    http.HandleFunc("/req/get", dealGetRequestHandler)
    http.ListenAndServe(":8005", nil)
    // 在golang中,你要构建一个web服务,必然要用到http.ListenAndServe
    // 第二个参数必须要有一个handler
}

实例讲解

server.go

package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    "net/http"
)

/*
使用net/http模块,开发一个简单的web server
    1、提供get请求
    2、提供post请求
http: 协议(和web服务器进行交互的规范,规则)
    Get: 从数据库读取数据,比如 查询订单
        - get请求参数是从url上直接读取(一般数据都比较少)
    Post: 创建新的数据,163购买票(在数据库会添加一条数据,购票记录)
        - 从http的body中获取的数据
    Put:  修改数据,更新支付宝上的用户信息(修改我的手机号)
    Delete: 删除数据库中数据
*/

/*
开发一个web服务器主要的步骤
第一步:路由
第二步:处理函数
    - 解析请求的数据(获取某一个商品,你需要把商品Id信息携带给后端)
        - 根据请求数据参数查询数据库
    - 响应数据(把从数据库读取的数据,给返回给浏览器或者请求方)
*/
func main() {
    //第一步:路由
    // http://127.0.0.1:8005 /req/get ?name=zhangsan
    http.HandleFunc("/req/get", dealGetHandler)
    /*
        "/req/get": 路由URL除去域名的哪一块(http://www.example.com /book/1/)
        dealGetHandler: 处理函数(处理服务请求)
    */
    http.HandleFunc("/req/post", dealPostHandler) // POST

    fmt.Println("http://127.0.0.1:8005/req/get")
    // 第三步:启动服务
    http.ListenAndServe(":8005", nil)
    /*
        addr: 当前server监听的端口号和ip
        handler:处理函数
    */
}

// 处理函数的名字用驼峰命名: xxxHandler函数名
// 第二步:处理函数(处理get请求)
/*
- 1)解析请求的数据(获取某一个商品,你需要把商品Id信息携带给后端)
    http.Request:解析url中的数据或者post请求中body的数据
- 2)响应数据(把从数据库读取的数据,给返回给浏览器或者请求方)
    http.ResponseWriter: 本质是一个interface接口,定义三个方法,进行返回数据
*/
func dealGetHandler(w http.ResponseWriter, r *http.Request) {
    //1)解析请求的数据
    query := r.URL.Query() // 返回  map[string][]string
    // 1.1 通过字典下标取get路由参数
    if len(query["name"]) > 0 {
        names := query["name"][0]
        fmt.Println("字典下标取值", names)
    }
    // 1.2 通过Get方法取值
    name2 := query.Get("name")
    fmt.Println("通过get方法取值", name2)
    fmt.Println(query)

    //2)响应数据
    //// 2.1 返回一个简单字符串
    //w.Write([]byte("hello world!"))
    // 2.2 返回一个json数据
    // 加上我们拿到了 name=zhangsan,我们到数据库取出了zhangsan用户的信息
    type Info struct {
        Name     string
        Password string
        Age      int
    }
    // 假设这是从数据库中取出
    u := Info{
        Name:     name2,
        Password: "123456",
        Age:      24,
    }
    json.NewEncoder(w).Encode(u)
}

type Info struct {
    Name     string `json:"name"`
    Password string `json:"password"`
}

// 和get请求是一模一样的写法,这是一个post请求
func dealPostHandler(w http.ResponseWriter, r *http.Request) {
    // r  *http.Request是结构的对象
    // r.URL.query()从url取请求参数
    // post请求从http的body中获取数据
    // r.Body是结构体 Request 中的字段 r.body 其实是*http.Request.body
    bodyContent, _ := ioutil.ReadAll(r.Body) // 返回的是一个byte
    //fmt.Printf("%T %v", bodyContent, bodyContent)
    // 获取string
    //strData := string(bodyContent)
    // 如何才能解析这个string字符串(str转结构体)
    var d Info
    //json.Unmarshal([]byte(strData), &d)
    json.Unmarshal(bodyContent, &d)
    fmt.Println("获取的数据name:", d.Name)
    fmt.Println(d)
    w.Write([]byte("hello world Post"))
}

client-post.go

package main

import (
    "fmt"
    "io/ioutil"
    "net/http"
    "strings"
)

func main() {
    url := "http://127.0.0.1:8005/req/post"
    // 模拟form表单提交数据 contentType := "application/x-www-form-urlencoded"
    // 传json数据: json contentType := "application/json"
    contentType := "application/json"
    data := `{
        "name": "root",
        "password": "123456"
    }`
    resp, _ := http.Post(url, contentType, strings.NewReader(data))
    b, _ := ioutil.ReadAll(resp.Body)
    fmt.Println(string(b))
}

client-get.go

package main

import (
    "fmt"
    "io/ioutil"
    "net/http"
    "net/url"
)

/*
使用net/http模块,作为web的客户端发送get请求
应用场景:
    1) 爬虫,获取页面数据
    2) 调用其他服务中的接口
*/
func main() {
    //// 1、直接通过url拼接处url字符串
    //apiUrl := "http://127.0.0.1:8005/req/get?name=zhangsan"
    apiUrl := "http://127.0.0.1:8005/req/get"

    // 2、通过url进行解析
    // http://127.0.0.1:8005/req/get?name=zhangsan
    // http://v5blog.cn/pages/d19d5a/#_01-%E6%89%93%E5%BC%80%E5%92%8C%E5%85%B3%E9%97%AD%E6%96%87%E4%BB%B6
    data := url.Values{}
    data.Set("name", "zhangsan")
    u, _ := url.ParseRequestURI(apiUrl)
    u.RawQuery = data.Encode()
    fmt.Println(u.String())

    resp, err := http.Get(u.String())
    if err != nil {
        fmt.Println(err)
    }
    body, _ := ioutil.ReadAll(resp.Body)
    fmt.Println(string(body))
}
赞(0) 打赏
未经允许不得转载:陈桂林博客 » golang之net-http简单介绍
分享到

大佬们的评论 抢沙发

全新“一站式”建站,高质量、高售后的一条龙服务

微信 抖音 支付宝 百度 头条 快手全平台打通信息流

橙子建站.极速智能建站8折购买虚拟主机

觉得文章有用就打赏一下文章作者

非常感谢你的打赏,我们将继续给力更多优质内容,让我们一起创建更加美好的网络世界!

支付宝扫一扫打赏

微信扫一扫打赏

登录

找回密码

注册