Title: Go 请求封装
Category: GOLANG
Tags:
- markdown
import ( "bytes" "encoding/json" "io" "io/ioutil" "mime/multipart" "net/http" "net/url" "strings" ) // Post send post request. func Post(url, contentType string, args map[string]string) (result string, err error) { if contentType == "" { contentType = "application/x-www-form-urlencoded" } resp, err := http.Post(url, contentType, strings.NewReader(argsEncode(args))) if err != nil { return } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { return } err = NewError(body) if err != nil { return } result = string(body) return } // VideoDescription 视频描述 type VideoDescription struct { Title string `json:"title"` // 视频素材的标题 Introduction string `json:"introduction"` // 视频素材的描述 } // Upload send post request. func Upload(uri, filename string, description *VideoDescription, srcFile io.Reader) (result []byte, err error) { buf := new(bytes.Buffer) // 文件 writer := multipart.NewWriter(buf) formFile, err := writer.CreateFormFile("media", filename) if err != nil { return nil, err } if _, err = io.Copy(formFile, srcFile); err != nil { return nil, err } contentType := writer.FormDataContentType() // 附加参数 if description != nil { jsonBytes, _ := json.Marshal(description) writer.WriteField("description", string(jsonBytes)) } writer.Close() // 发送之前必须调用Close()以写入结尾行 resp, err := http.Post(uri, contentType, buf) if err != nil { return } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { return } err = NewError(body) if err != nil { return } result = body return } // Download 下载非视频文件 func Download(uri string, dis io.Writer) (result []byte, err error) { var resp *http.Response resp, err = http.Get(uri) if err != nil { return } defer resp.Body.Close() ctype := resp.Header.Get("Content-Type") if strings.Index(strings.ToLower(ctype), "application/json") != -1 { result, err = ioutil.ReadAll(resp.Body) if err != nil { return } err = NewError(result) if err != nil { result = nil } } else { io.Copy(dis, resp.Body) } return } // PostJSON send post request. func PostJSON(url string, jsonObject interface{}) (result []byte, err error) { buf := new(bytes.Buffer) hjson := json.NewEncoder(buf) hjson.SetEscapeHTML(false) err = hjson.Encode(jsonObject) if err != nil { return } resp, err := http.Post(url, "application/json", buf) if err != nil { return } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { return } err = NewError(body) if err != nil { return } result = body return } // Get send get request. func Get(url string, args map[string]string) (result []byte, err error) { if args != nil { url += "?" + argsEncode(args) } resp, err := http.Get(url) if err != nil { return } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { return } err = NewError(body) if err != nil { return } result = body return } func argsEncode(params map[string]string) string { args := url.Values{} for k, v := range params { args.Set(k, v) } return args.Encode() }
使用
package main import ( "context" "encoding/json" "os" "time" "github.com/go-redis/redis/v8" "github.com/nilorg/go-wechat" "github.com/nilorg/pkg/logger" "github.com/nilorg/sdk/convert" "github.com/nilorg/sdk/signal" "github.com/pkg/errors" ) const ( envRedisAddrKey = "REDIS_ADDR" envRedisPasswordKey = "REDIS_PASSWORD" envRedisDbKey = "REDIS_DB" envAppIDKey = "WECHAT_APP_ID" envAppSecretKey = "WECHAT_APP_SECRET" envRefreshDurationKey = "WECHAT_REFRESH_DURATION" envRedisAccessTokenKey = "REDIS_ACCESS_TOKEN_KEY" envRedisJsAPITicketKey = "REDIS_JS_API_TICKET_KEY" ) var ( redisAddr string = "192.168.*.*:6379" redisPassword string = "Song****" redisDb int = 1 appID string = "wx642f9be216ef3fd6" appSecret string = "ce580a2bcd5de212a1a0d566c8a46a8b" refreshDuration time.Duration = time.Hour redisAccessTokenKey = wechat.RedisAccessTokenKey redisJsAPITicketKey = wechat.RedisJsAPITicketKey redisClient *redis.Client ) func init() { logger.Init() } func main() { if v := os.Getenv(envRedisAddrKey); v != "" { redisAddr = v } if v := os.Getenv(envRedisPasswordKey); v != "" { redisPassword = v } if v := os.Getenv(envRedisDbKey); v != "" { redisDb = convert.ToInt(v) } if v := os.Getenv(envAppIDKey); v != "" { appID = v } if v := os.Getenv(envAppSecretKey); v != "" { appSecret = v } if v := os.Getenv(envRefreshDurationKey); v != "" { refreshDuration = time.Duration(convert.ToInt64(v)) * time.Second } initRedis() logger.Debugln("初始化AccessToken和JsAPITicket") refresh() ticker := time.NewTicker(refreshDuration) go func() { // 异步 for range ticker.C { logger.Debugln("刷新AccessToken和JsAPITicket") refresh() } }() signal.AwaitExit() } func initRedis() { // 初始化Redis client := redis.NewClient(&redis.Options{ Addr: redisAddr, Password: redisPassword, DB: redisDb, }) _, err := client.Ping(context.Background()).Result() if err != nil { logger.Fatalf( "Init redis connection failed: %s ", errors.Wrap(err, "Ping redis failed"), ) } redisClient = client } func refresh() { token := refreshAccessToken() // 刷新AccessToken if token != "" { refreshJsAPITicket(token) // 刷新JsAPITicket } } // refreshAccessToken ... // https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140183 func refreshAccessToken() string { result, err := wechat.Get("https://api.weixin.qq.com/cgi-bin/token", map[string]string{ "appid": appID, "secret": appSecret, "grant_type": "client_credential", }) if err != nil { logger.Debugf("刷新AccessToken错误:%v", err) return "" } reply := new(wechat.AccessTokenReply) json.Unmarshal(result, reply) if err := redisClient.Set(context.Background(), redisAccessTokenKey, reply.AccessToken, time.Second*time.Duration(reply.ExpiresIn)).Err(); err != nil { logger.Errorf("redisClient.Set %s Value: %s Error: %s", redisAccessTokenKey, reply.AccessToken, err) } logger.Debugf("最新AccessToken: %s", reply.AccessToken) return reply.AccessToken } // refreshJsAPITicket ... // https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115 func refreshJsAPITicket(token string) { result, err := wechat.Get("https://api.weixin.qq.com/cgi-bin/ticket/getticket", map[string]string{ "access_token": token, "type": "jsapi", }) if err != nil { logger.Debugf("刷新Ticket错误:%v", err) return } reply := new(wechat.JsAPITicketReply) json.Unmarshal(result, reply) logger.Debugf("最新JsAPITicket: %s", reply.Ticket) if err := redisClient.Set(context.Background(), redisJsAPITicketKey, reply.Ticket, time.Second*time.Duration(reply.ExpiresIn)).Err(); err != nil { logger.Errorf("redisClient.Set %s Value: %s Error: %s", redisJsAPITicketKey, reply.Ticket, err) } }