這篇文章主要介紹了golang中http請求的示例分析,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

golang中的http請求
golang中擁有一個原生的http依賴庫:net/http,http服務器的建立還是http客戶端的開發,都會使用到這個依賴庫,這里主要講解時client部分,作為請求發起方應用于日常的接口測試,例示代碼如下:
get請求
package main
import (
"fmt"
"io/ioutil"
"net/http"
)
func main() {
//模擬一個get提交請求
resp, err := http.Get("http://127.0.0.1:12345/checkon")
if err != nil {
panic(err)
}
defer resp.Body.Close() //關閉連接
body, err := ioutil.ReadAll(resp.Body) //讀取body的內容
fmt.Println(string(body))
}返回結果
E:\go_project>go run testget.go
{
"code": 200,
"data": "",
"msg": "online",
"state": "success"
}post請求:
package main
import (
"fmt"
"io/ioutil"
"net/http"
"strings"
)
func main() {
//模擬一個post提交請求
resp, err := http.Post("http://www.baidu.com", "application/x-www-form-urlencoded", strings.NewReader("id=1"))
if err != nil {
panic(err)
}
//關閉連接
defer resp.Body.Close()
//讀取報文中所有內容
body, err := ioutil.ReadAll(resp.Body)
//輸出內容
fmt.Println(string(body))
}上面的post請求以form的方式,最后會返回一個頁面
這里說明一下以下這行代碼
defer resp.Body.Close()
首先是defer, Go的defer語句用來調度一個函數調用(被延期的函數),使其在執行defer的函數即將返回之前才被運行,被延期執行的函數,它的參數(包括接受者)實在defer執行的時候被求值的,而不是在調用執行的時候。也就是說被延期執行的函數的參數是按正常順序被求值的,簡單理解為,無論defer對應的代碼行放在代碼段的哪個位置,defer是在return前執行的代碼行,但defer代碼行中的參數是需要先聲明再調用的,對應響應中的處理,golang的Response.Body需要被關閉的,body實際上是一個嵌套了多層的net.TCPConn:
bufio.Reader,這層嘗試將多次小的讀操作替換為一次大的讀操作,減少系統調用的次數,提高性能;
io.LimitedReader,tcp連接在讀取完body后不會關閉,繼續讀會導致阻塞,所以需要LimitedReader在body讀完后發出eof終止讀取;
chunkedReader,解析chunked格式編碼(如果不是chunked略過);
bodyEOFSignal,在讀到eof,或者是提前關閉body時會對readLoop發出回收連接的通知;
gzipReader,解析gzip壓縮(如果不是gizp壓縮略過);
從上面可以看出如果body既沒有被完全讀取,也沒有被關閉,那么這次http事務就沒有完成,除非連接因超時終止了,否則相關資源無法被回收,所以需要我們進行關閉連接的操作,這個是很多golang新手會忽略的一個點,作為client端處理response的時候,body一定要close,否則會造成GC回收不到,繼而產生內存泄露
帶json的post請求
我們大部分應用到的restful接口都是用json格式的請求體,對應的golang的http請求也會有相關的方式post json請求體
package main
import (
"fmt"
"io/ioutil"
"net/http"
"bytes"
"encoding/json"
)
type HttpData struct {
Flag int `json:"flag"`
Msg string `json:"msg"`
}
func main() {
url := "http://127.0.0.1:12345/postdata"
contentType := "application/json;charset=utf-8"
var httpdata HttpData
httpdata.Flag = 1
httpdata.Msg = "terrychow"
b ,err := json.Marshal(httpdata)
if err != nil {
fmt.Println("json format error:", err)
return
}
body := bytes.NewBuffer(b)
resp, err := http.Post(url, contentType, body)
if err != nil {
fmt.Println("Post failed:", err)
return
}
defer resp.Body.Close()
content, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("Read failed:", err)
return
}
fmt.Println("header:", resp.Header)
fmt.Println("content:", string(content))
}執行結果響應
E:\go_project>go run gohttptest.go
header: map[Content-Type:[application/json] Content-Length:[78] Server:[Werkzeug/0.14.1 Python/2.7.15] Date:[Thu, 06 Dec 2018 16:35:11 GMT]]
content: {
"code": 200,
"data": 1,
"msg": "terrychow",
"state": "success"
}對于常用的get和post請求基本上就以照上面的版本執行,當然我們現在需要做的是http接口的測試,那就需要引入測試框架進行相關的校驗,本文先講解用之前提到的gocheck來進行斷言
golang中的http接口測試
引入gocheck之后我們得到了以下的腳本:
package hello_test
import (
"testing"
"fmt"
"strconv"
"io/ioutil"
"net/http"
"bytes"
"encoding/json"
. "gopkg.in/check.v1"
)
var a int =1
// Hook up gocheck into the "go test" runner.
func Test(t *testing.T) { TestingT(t) }
type MySuite struct{}
type HttpData struct {
Flag int `json:"flag"`
Msg string `json:"msg"`
}
var _ = Suite(&MySuite{})
var testurl string ="http://127.0.0.1:12345"
func (s *MySuite) SetUpSuite(c *C) {
str3:="第1次套件開始執行"
fmt.Println(str3)
//c.Skip("Skip TestSutie")
}
func (s *MySuite) TearDownSuite(c *C) {
str4:="第1次套件執行完成"
fmt.Println(str4)
}
func (s *MySuite) SetUpTest(c *C) {
str1:="第"+strconv.Itoa(a)+"條用例開始執行"
fmt.Println(str1)
}
func (s *MySuite) TearDownTest(c *C) {
str2:="第"+strconv.Itoa(a)+"條用例執行完成"
fmt.Println(str2)
a=a+1
}
func (s *MySuite) TestHttpGet(c *C) {
geturl := fmt.Sprintf("%v/checkon", testurl)
respget, err := http.Get(geturl)
if err != nil {
panic(err)
}
defer respget.Body.Close() //關閉連接
body, err := ioutil.ReadAll(respget.Body) //讀取body的內容
var gdat map[string]interface{} //定義map用于解析resp.body的內容
if err := json.Unmarshal([]byte(string(body)), &gdat); err == nil {
fmt.Println(gdat)
} else {
fmt.Println(err)
}
var gmsg=gdat["msg"]
c.Assert(gmsg, Equals, "terrychow") //模擬失敗的斷言
}
func (s *MySuite) TestHttpPost(c *C) {
url := fmt.Sprintf("%v/postdata", testurl)
contentType := "application/json;charset=utf-8"
var httpdata HttpData
httpdata.Flag = 1
httpdata.Msg = "terrychow"
b ,err := json.Marshal(httpdata)
if err != nil {
fmt.Println("json format error:", err)
return
}
body := bytes.NewBuffer(b)
resp, err := http.Post(url, contentType, body)
if err != nil {
fmt.Println("Post failed:", err)
return
}
defer resp.Body.Close()
content, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("Read failed:", err)
return
}
var dat map[string]interface{} //定義map用于解析resp.body的內容
if err := json.Unmarshal([]byte(string(content)), &dat); err == nil {
fmt.Println(dat)
} else {
fmt.Println(err)
}
var msg=dat["msg"]
c.Assert(msg, Equals, "terrychow") //模擬成功的斷言
}最后的輸出內容:
E:\go_project>go test -v gocheckhttp_test.go === RUN Test 第1次套件開始執行 第1條用例開始執行 map[code:200 data: msg:online state:success] 第1條用例執行完成 ---------------------------------------------------------------------- FAIL: gocheckhttp_test.go:56: MySuite.TestHttpGet gocheckhttp_test.go:72: c.Assert(gmsg, Equals, "terrychow") ... obtained string = "online" ... expected string = "terrychow" 第2條用例開始執行 map[msg:terrychow state:success code:200 data:1] 第2條用例執行完成 第1次套件執行完成 OOPS: 1 passed, 1 FAILED --- FAIL: Test (0.02s) FAIL FAIL command-line-arguments 0.613s
輸出的結果符合預期,這也是比較基本的http接口測試
感謝你能夠認真閱讀完這篇文章,希望小編分享的“golang中http請求的示例分析”這篇文章對大家有幫助,同時也希望大家多多支持創新互聯成都網站設計公司,關注創新互聯成都網站設計公司行業資訊頻道,更多相關知識等著你來學習!
另外有需要云服務器可以了解下創新互聯scvps.cn,海內外云服務器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務器、裸金屬服務器、網站設計器、香港服務器、美國服務器、虛擬主機、免備案服務器”等云主機租用服務以及企業上云的綜合解決方案,具有“安全穩定、簡單易用、服務可用性高、性價比高”等特點與優勢,專為企業上云打造定制,能夠滿足用戶豐富、多元化的應用場景需求。
當前題目:golang中http請求的示例分析-創新互聯
鏈接地址:http://www.yijiale78.com/article34/dicgse.html
成都網站建設公司_創新互聯,為您提供網站制作、網站設計公司、網站改版、App開發、網站排名、移動網站建設
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯