乐趣区

关于go:用go实现getpost请求调用api

最近的一次 demo,相当于一次温习吧,把踩的坑都记录一遍

先温习一下调用接口的过程

  1. 须要 url
  2. 是 get 办法,还是 post 办法?
  3. url 须要加参数吗?
  4. 序列化?

1. 返回的 response 的 body 默认类型是[]byte

body, err := ioutil.ReadAll(resp.Body)
// 查看返回值的类型
fmt.Println(reflect.TypeOf(body))
// 终端显示 body 的类型是[]uint8

2. 将[]byte 转换成 string

转换过程中依据《go 专家编程》讲的来看,须要进行内存拷贝

fmt.Println(string(body))

3. 将获取到的 json 中提取某一个对象

留神在获取的 response 时,body 的默认数据类型是[]byte, 须要转换成 string,能力显示成 json 难看的格局,通过变成的 string 格局来获取某一个 key-value

//go get "github.com/thedevsaddam/gojsonq"
jsonX := string(body)
t := gojsonq.New().FromString(jsonX).Find("unique_token")
// 因为返回的 t 是一个空接口类型,须要类型断言转换成 string 类型
return t.(string)

4.go 发送 post 申请调用 api

func SubmitOrder(params []byte) {
    // 申明下单的 url
    PostOrderUrl := "https://www.testapi.com/test"

    // 设置 post 申请, 第三个参数传 byte 类型, 很要害!req, err := http.NewRequest("POST", PostOrderUrl, bytes.NewBuffer(params))
    if err != nil {log.Println(err)
    }

    // 受权!!!// 这里也很要害,千万不要设置漏了,否则可能后端接口返回不出正确的后果!req.Header.Set("Content-Type", "application/json")
    req.Header.Set("authorization", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiMzdlYWMwMTMtOTM5Yy00NThjLTgxMDktYmM5MDFjMTIyY2I0IiwiZXhwIjoxNzMzODQ2NTEzfQ._p6nCjIx1nq6sbMa4B-yJ9P_vThJESsF5tLIRoMRZXA")

    // 获取客户端对象,发送申请
    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {log.Println(err)
    }
    defer resp.Body.Close()

    // 读取返回值
    res, err := ioutil.ReadAll(resp.Body)
    if err != nil {fmt.Println(err)
    }
    fmt.Println(string(res))

}

5. 获取空接口类型 的类型或者值

xx1:=reflect.Typeof(x)
xx2:=reflect.Valueof(x)

6. 强制转换空接口类型

tt 是 interface{}类型,每一个 interface{}类型中都保留了他自身的 value 和 type,须要通过发射获取值,实现办法见下面

tt := int(t.(float64))

7. 定义的一个办法返回不同类型的值怎么实现?

将这些返回值用一个 struct 封装起来
而后定义返回参数为 interface{}实现
如何获取返回的值变为原来的 struct 类型呢?
类型断言!
比方:

type Mystruct struct{
  a int 
  b string
}
func test() interface{}{
    // 解决逻辑
       ....
 
    var mystruct =new(Mystruct)
    mystruct.a=1
    mystruct.b="balabala"
    return mystruct
}

Value := test()
// 不确定空接口理论的类型能够用 reflect.Typeof()来确定
//reflect.Typeof(Value)===> 他会返回 Mystruct, 如同也可能是 *Mystruct,能够测试一下!V:=Value.(Mystruct)

8. 将定义好的构造体序列化

// 定义的构造体
type Product struct {
    Type             int    `json:"type" `
    ProductNo        string `json:"product_no" `
    Amount           int    `json:"amount"`
    ElectricityHours int    `json:"electricity_hours" `
    HashRateNo       string `json:"hashrate_no" `
}

type CreateOrderParams struct {Products    []Product `json:"products"`
    UniqueToken string    `json:"unique_token" `
}

// 结构须要传递的参数
    params := new(CreateOrderParams)

// 给结构好的构造体赋值
    params.UniqueToken = uniqueToken
    var p Product
    p.Type = tt.Type
    p.ProductNo = tt.Code
    p.Amount = 10
    p.ElectricityHours = 240
    var products []Product
    products = append(products, p)
    params.Products = products

// 将构造体序列化,转化为 json 格局,返回的后果是[]byte 类型
    res, err := json.Marshal(&params)
    if err != nil {println(err.Error())
    }

9. go 发送 get 申请调用 api

func GetToken() string {
    // 申明要获取 unique_token 的接口
    reqUniqueTokenUrl := "https://this.is.test.url:8888/v1/users/token"

    // 设置 get 申请类型, 所以第三个参数为 nil
    req, err := http.NewRequest("GET", reqUniqueTokenUrl, nil)
    if err != nil {log.Println(err)
    }

    // 设置申请头 header, 携带 token 身份认证
    req.Header.Set("authorization", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ1.eyJuYW1lIjoiMzdlYWMwMTMtOTM5Yy00NThjLTgxMDktYmM5MDFjMTIyY2I0IiwiZXhwIjoxNzMzODQ2NTEzfQ._p6nCjIx1nq6sbMa4B-yJ9P_vThJESsF5tLIRoMRZXA")

    // 获取客户端对象,执行申请
    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {log.Println(err)
        panic("ops!,get unique token url err!")
    }
    defer resp.Body.Close()

    // 打印后果
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {log.Println(err)
        panic("ops!,get unique token url err!")
    }
    fmt.Println(string(body))

    // 在返回的 JSON 对象中依据 key 获取 value
    jsonX := string(body)
    t := gojsonq.New().FromString(jsonX).Find("unique_token")
    // 因为返回的 t 是一个空接口类型,须要类型断言转换成 string 类型
    return t.(string)
}

最初,展现我做试验的所有代码,有些数据是伪数据,按需替换哈!

package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "github.com/thedevsaddam/gojsonq"
    "io/ioutil"
    "log"
    "net/http"
)

type Product struct {
    Type             int    `json:"type" `
    ProductNo        string `json:"product_no" `
    Amount           int    `json:"amount"`
    ElectricityHours int    `json:"electricity_hours" `
    HashRateNo       string `json:"hashrate_no" `
}

type CreateOrderParams struct {Products    []Product `json:"products"`
    UniqueToken string    `json:"unique_token" `
}

type Response struct {
    Code string
    Type int
}

func main() {
    // 获取 token
    uniqueToken := GetToken()
    // 获取商品类型
    t := GetGoodsInfo()
    // 这里是个大坑, 通过 reflect.Typeof(t)发现类型是 t 的理论类型是 *Response, 所以类型断言肯定要是指针类型的!tt := t.(*Response)

    // 结构须要传递的参数
    params := new(CreateOrderParams)

    // 给结构好的构造体赋值
    params.UniqueToken = uniqueToken
    var p Product
    p.Type = tt.Type
    p.ProductNo = tt.Code
    p.Amount = 10
    p.ElectricityHours = 240
    var products []Product
    products = append(products, p)
    params.Products = products

    // 将构造体序列化,转化为 json 格局,返回的后果是[]byte 类型
    res, err := json.Marshal(&params)
    if err != nil {println(err.Error())
    }

    // 提交订单
    SubmitOrder(res)
}

// GetGoodsInfo 获取商品信息
func GetGoodsInfo() interface{} {
    // 申明要调用获取商品信息的接口
    reqGoodsUrl := "https://this.is.test.url/test"

    // 调用接口
    req, err := http.NewRequest("GET", reqGoodsUrl, nil)
    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {log.Println(err)
    }
    defer resp.Body.Close()
    // 打印返回后果
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {log.Println(err)
    }
    // Todo: 如何将后果转换成映射到 Products
    jsonX := string(body)
    t := gojsonq.New().FromString(jsonX).Find("type")
    //Todo: 要点!!!接口类型的 float64 转换成 int
    //reflect.TypeOf(t) => float64
    tt := int(t.(float64))

    c := gojsonq.New().FromString(jsonX).Find("code")
    code := c.(string)
    fmt.Println("test", code)

    res := new(Response)
    res.Type = tt
    res.Code = code

    return res

}

// GetToken 获取 token
func GetToken() string {
    // 申明要获取 unique_token 的接口
    reqUniqueTokenUrl := "https://this.is.test.url:8888/v1/users/token"

    // 设置 get 申请类型, 所以第三个参数为 nil
    req, err := http.NewRequest("GET", reqUniqueTokenUrl, nil)
    if err != nil {log.Println(err)
    }

    // 设置申请头 header, 携带 token 身份认证
    req.Header.Set("authorization", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ1.eyJuYW1lIjoiMzdlYWMwMTMtOTM5Yy00NThjLTgxMDktYmM5MDFjMTIyY2I0IiwiZXhwIjoxNzMzODQ2NTEzfQ._p6nCjIx1nq6sbMa4B-yJ9P_vThJESsF5tLIRoMRZXA")

    // 获取客户端对象,执行申请
    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {log.Println(err)
        panic("ops!,get unique token url err!")
    }
    defer resp.Body.Close()

    // 打印后果
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {log.Println(err)
        panic("ops!,get unique token url err!")
    }
    fmt.Println(string(body))

    // 在返回的 JSON 对象中依据 key 获取 value
    jsonX := string(body)
    t := gojsonq.New().FromString(jsonX).Find("unique_token")
    // 因为返回的 t 是一个空接口类型,须要类型断言转换成 string 类型
    return t.(string)
}

// SubmitOrder 提交订单
func SubmitOrder(params []byte) {
    // 申明下单的 url
    PostOrderUrl := "https://dev.cookiehash.org:31145/v1/orders"

    // 设置 post 申请, 第三个参数传 byte 类型
    req, err := http.NewRequest("POST", PostOrderUrl, bytes.NewBuffer(params))
    if err != nil {log.Println(err)
    }

    // 受权
    req.Header.Set("Content-Type", "application/json")
    req.Header.Set("authorization", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiMzdlYWMwMTMtOTM5Yy00NThjLTgxMDktYmM5MDFjMTIyY2F0IiwiZXhwIjoxNzMzODQ2NTEzfQ._p6nCjIx1nq6sbMa4B-yJ9P_vThJESsF5tLIRoMRZXA")

    // 获取客户端对象,发送申请
    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {log.Println(err)
    }
    defer resp.Body.Close()

    // 读取返回值
    res, err := ioutil.ReadAll(resp.Body)
    if err != nil {fmt.Println(err)
    }
    fmt.Println(string(res))
}

参考链接:
go 发送 get 申请
go 发送 post 申请

退出移动版