zoukankan      html  css  js  c++  java
  • Golang模块之HTTP

    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
    ",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
    ",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
    ", 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
    ", 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
    ", string(body))
    }
    
  • 相关阅读:
    AppScan扫描教程
    iis发布网站可能遇到的问题及解决方法
    apache、nginx、iis日志记录的各个字段内容与含义
    nmap的使用教程
    ubuntu下编译wiringPi
    配置NAT
    华为OSPF与ACL综合应用实例讲解
    浮动静态路由及负载均衡
    静态路由及默认路由基本配置
    利用三层交换机实现VLAN间路由
  • 原文地址:https://www.cnblogs.com/jasonminghao/p/12378018.html
Copyright © 2011-2022 走看看