0、前言

Go语言中内置net/http包提供了HTTP客户端和服务端的实现

1、HTTP服务端

模拟一个HTTP服务端。

package main

import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
) // 定义客户端提交的post请求的json数据内容
type Auth struct {
Username string `json: username`
Password string `json: password`
} // 定义服务端返回json数据给客户端的内容
type Resp struct {
Code string `json: code`
Msg string `json: msg`
} func f1(w http.ResponseWriter,r *http.Request){
str := `from home`
w.Write([]byte(str))
} func f2(w http.ResponseWriter,r *http.Request){
b,err := ioutil.ReadFile("./html/index.html") // 读取到html文件(byte类型切片)
if err != nil {
w.Write([]byte(fmt.Sprintf("%v",err)))
}
w.Write(b) // 返回响应数据(必须传入byte类型切片)
} func f3(w http.ResponseWriter,r *http.Request){
// 对于GET请求,参数都放在URL上(query param),请求体中是没有数据的
queryParam := r.URL.Query() // 自动帮我们识别URL中的urlParam
query := queryParam.Get("query")
page := queryParam.Get("page")
fmt.Println(query,page)
fmt.Println(r.URL) // 查看请求url
fmt.Println(r.Method) // 查看请求方法
fmt.Println(ioutil.ReadAll(r.Body)) // 查看请求的body
w.Write([]byte("ok"))
} // post接口接收json数据
func f4(w http.ResponseWriter,r *http.Request){ // 检查是否为POST请求
if r.Method != "POST"{
w.WriteHeader(405) // 返回错误代码
return
}
body,_ := ioutil.ReadAll(r.Body)
//body_str := string(body)
//fmt.Println(body_str) var auth Auth
var result Resp
if err := json.Unmarshal(body,&auth);err == nil {
// 拿到json数据
fmt.Printf("用户名:%v 密码:%v",auth.Username,auth.Password) result.Code = "200"
result.Msg = "Success"
// 将返回的数据转化成json格式
ret,_ := json.Marshal(result)
w.Write(ret)
}else{
result.Code = "500"
result.Msg = "Failed"
ret,_ := json.Marshal(result)
w.Write(ret)
}
} func main(){
http.HandleFunc("/home",f1)
http.HandleFunc("/index",f2)
http.HandleFunc("/xxx",f3)
http.HandleFunc("/login",f4) // 启动HTTP服务(监听地址和端口)
http.ListenAndServe("0.0.0.0:9090",nil)
}

2、HTTP客户端

HTTP客户端能够发送HTTP请求,如:GET/POST

2.1、GET请求示例

package main

import (
"fmt"
"io/ioutil"
"net/http"
"net/url"
) // net/http client func main(){
resp,err := http.Get("http://127.0.0.1:9090/index")
if err != nil {
fmt.Printf("get url failed,err:%v\n",err)
return
}
body,err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Printf("read resp.Body failed,err:%v",err)
}
fmt.Println(string(body)) }

2.2、GET请求URL带参数示例

我们可以在发送Get请求的时候在url上携带参数,例如:http://xx/xx?query=xx&page=xx

package main

import (
"fmt"
"io/ioutil"
"net/http"
"net/url"
) // net/http client func main(){
//resp,err := http.Get("http://127.0.0.1:9090/xxx?query=jack&page=1")
data := url.Values{} // url encode(携带get请求参数)
urlObj,_ := url.Parse("http://127.0.0.1:9090/xxx")
data.Set("query","jack")
data.Set("page","1")
queryStr := data.Encode() // url encode之后的地址
fmt.Println(queryStr)
urlObj.RawPath = queryStr // 添加url
req,err := http.NewRequest("GET",urlObj.String(),nil) // 发送请求
resp,err := http.DefaultClient.Do(req) if err != nil {
fmt.Printf("get url failed,err:%v\n",err)
return
}
defer resp.Body.Close() // 关闭连接 body,err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Printf("read resp.Body failed,err:%v",err)
}
fmt.Println(string(body))
}

短连接

默认情况下浏览器开启了长连接,如果请求频繁的话,可能会存在长连接还没有关闭,又启动了新的连接,一直这样循环下去,就会导致连接超额,每个连接都会占用资源/网络IO,那么其实可以通过关闭长连接的方式来避免这个问题

// 禁用KeepAlive的client
tr := &http.Transport{
DisableKeepAlives: true,
}
client := http.Client{
Transport: tr,
}
client.Do(req)

2.3、POST请求携带Json数据示例1

很多时候,我们在实现POST请求都需要携带对应规范的json格式数据,例如

{
"username":"admin",
"password":"123456"
}

实现上面的规范来提交json数据

package main

import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
) type auth struct {
Username string `json: username`
Password string `json: password`
} func main(){
// post请求
auths := auth{"admin","123456"}
bs,_ := json.Marshal(auths) // 将结构体数据转换成json格式
resp,_ := http.Post("http://127.0.0.1:9090/login","application/json", bytes.NewBuffer([]byte(bs)))
body, _ := ioutil.ReadAll(resp.Body)
fmt.Printf("Post request with json result: %s\n", string(body))
}

2.4、POST请求携带Json数据示例1

很多时候,我们在实现POST请求都需要携带对应规范的json格式数据,例如

{
"username":"admin",
"password":"123456"
}

实现上面的规范来提交json数据

package main

import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
) // 我们需要在结构体中添加注解来映射对应的key
type auth struct {
Username string `json: username`
Password string `json: password`
} func main(){
// post请求
auths := auth{"admin","123456"}
bs,_ := json.Marshal(auths) // 将结构体数据转换成json格式
resp,_ := http.Post("http://127.0.0.1:9090/login","application/json", bytes.NewBuffer([]byte(bs)))
body, _ := ioutil.ReadAll(resp.Body)
fmt.Printf("Post request with json result: %s\n", string(body))
}

2.5、POST请求携带Json数据示例2

很多时候,我们在实现POST请求都需要携带对应规范的json格式数据,例如

{
"username":"admin",
"password":"123456"
}

实现上面的规范来提交json数据

package main

import (
"bytes"
"encoding/json"
"fmt"
"go_dev/Project/EyeSkyAgent/conf"
"io/ioutil"
"net/http"
) type auth struct {
Username string `json: username`
Password string `json: password`
} func main(){
// post请求
var data auth
data.Username = "Jack"
data.Password = "Jack123"
bs, err := json.Marshal(data) reader := bytes.NewReader(bs)
request, err := http.NewRequest("POST", "http://127.0.0.1:9090/login", reader)
if err != nil{
conf.Logger.Error("请求server端失败...")
}
// 携带头部
request.Header.Set("Content-Type", "application/json;charset=UTF-8")
client := http.Client{}
// 返回服务端的响应数据
resp, err := client.Do(request)
if err != nil {
fmt.Println("请求获取响应失败")
}
body, _ := ioutil.ReadAll(resp.Body)
fmt.Printf("Post request with json result: %s\n", string(body))
}

Golang模块之HTTP的更多相关文章

  1. Golang 模块(Module)官方手册

    官方原文: https://github.com/golang/go/wiki/Modules Go 1.11包括此处建议的对版本模块的初步支持.模块是Go 1.11中的实验性加入功能,并计划纳入反馈 ...

  2. golang模块viper读取配置文件

    一.介绍 Viper是一个方便Go语言应用程序处理配置信息的库.它可以处理多种格式的配置.它支持的特性: 设置默认值 从JSON.TOML.YAML.HCL和Java properties文件中读取配 ...

  3. golang常用模块介绍

    golang模块 一.命令行库Cobra Cobra提供简单的接口来创建强大的现代化CLI接口,比如git与go工具.Cobra同时也是一个程序, 用于创建CLI程序 https://www.jian ...

  4. 使用 Elastic Stack 来监控和调优 Golang 应用程序

    Golang 因为其语法简单,上手快且方便部署正被越来越多的开发者所青睐,一个 Golang 程序开发好了之后,势必要关心其运行情况,今天在这里就给大家介绍一下如果使用 Elastic Stack 来 ...

  5. Golang的模块管理Module

    Golang 1.11版本终于支持了官方的模块依赖管理功能,1.11以前想要实现依赖管理只能够通过借助第三方库来实现,1.11以前的版本Golang项目必须依赖以GOPATH,从当前版本开始Golan ...

  6. 用Golang为Python编写模块

    Go里面需要显示的引入C模块, 让编译器支持生成动态链接库, 并且在代码中可以使用C语言的数据类型,这个至关重要. Calling Go code from Python code 摘取一个最简单例子 ...

  7. 设计自用的golang日志模块

    设计自用的golang日志模块 golang的原生日志模块不能满足需求,而开源的第三方包,也不完全够用.用户较多的logrus,却没有rotate功能,这已经是众所周知的.对于运维来说,当然是希望日志 ...

  8. 治理Go模块 服务治理 中台业务 Golang的net.Conn接口,double close

    小结: 1.中台业务 前台业务 快车.专车.顺风车,在滴滴这些业务线叫做前台服务,他们有一些共同的特性,都有司机信息,订单的状态,收银,账号等等这些业务逻辑,我们会把专门的业务逻辑集合起来,形成专职的 ...

  9. Golang中基础的命令行模块urfave/cli

    前言相信只要部署过线上服务,都知道启动参数一定是必不可少的,当你在不同的网络.硬件.软件环境下去启动一个服务的时候,总会有一些启动参数是不确定的,这时候就需要通过命令行模块去解析这些参数,urfave ...

随机推荐

  1. 使用typescript改造koa开发框架

    强类型的 TypeScript 开发体验和维护项目上相比 JavaScript 有着明显的优势,那么对常用的脚手架进行改造也就势在必行了. 接下来开始对基于 koa 框架的 node 后端脚手架进行改 ...

  2. 关于 JavaSrcipt 前端开发的建议:模块化开发

    JavaScript 是一种优秀的脚本语言. 在 JavaScript 的诞生之初,便于 浏览器 密不可分,如今它更是到了服务器中大展身手. 但是这里不叙述服务端的开发建议. Script 翻译过来就 ...

  3. springcloud 依赖版本问题

    SpringCloud 版本: 版本名称 版本 Finchley snapshot版 Edgware snapshot版 Dalston SR1 当前最新稳定版本 Camden SR7 稳定版本 Br ...

  4. 我的一个react路由之旅(步骤及详图)

    今天开始react一个重要部分的xiao~习,路由~(过程截图,最后附代码) 以下代码只能骗糊涂蛋子,没错,就是我自己,不要打算让我敲出多高级的东西~ 理论性知识几乎没有,请不要打算让我给你说原理啥的 ...

  5. Java面试技巧—如何自我介绍

    在企业面试环节中“自我介绍”这个老生常谈的话题就不用多说什么了,面试官必定会问的.那么如何在自我介绍的时候就能够打动面试官,吸引面试官对面试者的兴趣?如何进行自我介绍比较好?有没有什么方式方法呢?当然 ...

  6. python学习记录(五)

    20180829--https://www.cnblogs.com/fnng/archive/2013/04/20/3032563.html 字典 字典的使用 现实中的字段及在Python中的字段都进 ...

  7. 20194651—自动生成四则运算题第一版报告chris

    1.需求分析: (1)自动生成四则运算算式(+ - *  /),或两则运算(+  -). (2)剔除重复算式. (3)题目数量可定制. (4)相关参数可控制. (5)生成的运算题存储到外部文件中. 2 ...

  8. sql中常量和变量的引用

    String name =jtf.getText().trim(); String sql="select * from stu where stuname='  "+name+& ...

  9. BZOJ 1042 [HAOI2008]硬币购物(完全背包+容斥)

    题意: 4种硬币买价值为V的商品,每种硬币有numi个,问有多少种买法 1000次询问,numi<1e5 思路: 完全背包计算出没有numi限制下的买法, 然后答案为dp[V]-(s1+s2+s ...

  10. Pycharm学习记录---同一目录下无法import明明已经存在的.py文件

    转自:https://blog.csdn.net/l8947943/article/details/79874180 问题描述: 如图:同目录下明明存在相应文件,在导入时却出现带有红色波浪线,说没有相 ...