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))
    }
    
  • 相关阅读:
    Spring基础知识
    Hibernate基础知识
    Struts2基础知识
    在eclipse里头用checkstyle检查项目出现 File contains tab characters (this is the first instance)原因
    java后台获取cookie里面值得方法
    ckplayer 中的style.swf 中的 style.xml 中的修改方法
    java hql case when 的用法
    Windows下Mongodb安装及配置
    Mongodb中经常出现的错误(汇总)child process failed, exited with error number
    Mac 安装mongodb
  • 原文地址:https://www.cnblogs.com/jasonminghao/p/12378018.html
Copyright © 2011-2022 走看看