首页 > 其他分享 >Golang - net/http 笔记

Golang - net/http 笔记

时间:2023-06-20 11:01:36浏览次数:40  
标签:http string err rep req Golang Header net


Server

package main

import (
	"fmt"
	"log"
	"net/http"
)

// 模拟实现 Handler 接口
type Bar struct {}

func (b Bar) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	tgt := req.URL.Query().Get("name")
	fmt.Fprintf(w, "Hi %v", tgt)
}

func main() {
    // 创建路由, 方式 1: Handle(), 参数是 Handle 接口
	http.Handle("/bar", Bar{})

    // 创建路由, 方式 2: HandleFunc(), 参数是满足要求的 func()
	http.HandleFunc("/foo", func(w http.ResponseWriter, req *http.Request) {
		tgt := req.URL.Query().Get("name")
		fmt.Fprintf(w, "Hello %v", tgt)
	})

    // 启动服务, log.Fatal() 输出错误信息并退出
	log.Fatal(http.ListenAndServe(":9999", nil))
}

Client

发起请求

GET

直接请求

// 发起请求
rep, err := http.Get("http://127.0.0.1:9998/sayhello")

// 这里做一个处理 err 的示例, 文档中其他位置都忽略错误处理
if err != nil {
    log.fatel(err)
}

// 这个很重要, 回收资源
defer rep.Body.Close()

自定义请求

// client
c := http.DefaultClient //  实际实现 c := &http.Client{}

// request
req, _ := http.NewRequest("GET", "http://127.0.0.1:9998/x", nil)

// 加header
req.Header.Add("token", "xxx")  // Add, 如果变量不存在则设置, 如果存在则不设置
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")  // Set, 如果变量存在则设置, 不存在则不设置

// 加参数
req.URL.RawQuery = url.Values{
	"key": {"v"},
}.Encode()

// client 发送 request, 并且拿到返回
rep := c.Do(req)
defer rep.Body.Close()  // 回收资源

补充

两种 header 的设置方法
// 1. req.Header.Add(k, v)
req.Header.Add("token", "xxx")

// 2. 因为 Header 类型为 map[string][]string, 可以定义一个同类型的 Header 数据, 然后赋值
req.Header = map[string][]string{
	"token": {"xxx"},
	"num": {"1", "2", "3"},
}
两种参数的设置方法
// 1. req.URL.RawQuery = url.Values{}, 虽然 url.Values 类型也是 map[string][]string, 但是直接使用 map 则没有 Encode 方法, 不自找麻烦了
req.URL.RawQuery = url.Values{
	"key": {"v"},
}.Encode()

// 2. 使用 Sprinf 将参数拼接到 url 中
newURL := fmt.Sprintf("https://%v/$v?%v=$v", url, uri, k, v)

POST

直接请求

// http.Post 只能设置 url, contentType 和 body, 如果需要设置 header, 需要 http.DefaultClient
rep, err := http.Post("http://127.0.0.1:9998/y", "application/json", strings.NewReader("name=Tim"))

if err != nil {
	log.fatal(err)
}

defer rep.Body.Close()

自定义请求

// client
c := http.DefaultClient //  实际实现 c := &http.Client{}

// 模拟一个数据类型, 先进行序列化, 再将 []byte 转为 io.Reader
data := []int{1, 2, 3}
marshal, _ := json.Marshal(data)
body := bytes.NewReader(marshal)

// request
req, _ := http.NewRequest("POST", "http://127.0.0.1:9998/x", body)

// 加header
req.Header.Add("token", "xxx")  // 如果变量不存在则设置, 如果存在则不设置

// client 发送 request
rep := c.Do(req)
defer rep.Body.Close()

补充

两种 io.Reader 的获取方法(造 body)
// 1. []byte -> io.Reader, 需要先将 go 的数据类型序列化为 []byte
data := []int{1, 2, 3}
marshal, _ := json.Marshal(data)
body := bytes.NewReader(marshal)

// 2. string -> io.Reader
strings.NewReader("name=Tim"))

读取 response 数据

读所有

all, _ := ioutil.ReadAll(rep.Body)

根据字节分片读

r := make([]byte, 0, 1024)   // 结果
buf := make([]byte, 0, 128)  // 缓存

// 一直读, 读到出现 EOF 为止
for {
    // n 是读取的字节个数
    n, err := rep.Body.Read(buf)

    // 如果是 EOF 错误, n 为末尾的字节位置, 将 buf 切片并追加到 r 中, 返回
    if err == io.EOF {
        r = append(r, buf[:n]...)
       	break
    }

    // 如果有报错且报错不是 EOF, 则退出
    if err != nil && err != io.EOF {
        log.Println(err)
        break
    }

	// 为出现 EOF, 则将 buf 内所有内容全部追加到 r
    r = append(r, buf[:]...)
}

// 打印结果
fmt.Println(string(r))

取得结果

  • 强转
// []byte --> string
string(body)
  • 反序列化: json --> struct or map
  • 第三方包解析: 从 json 直接取值


标签:http,string,err,rep,req,Golang,Header,net
From: https://blog.51cto.com/u_16165803/6521288

相关文章

  • Golang - 日志
    官方Log包方法输出到logger.out:log.Print(),log.Printf(),log.Println()输出到logger.out,再执行os.Exit(1):log.Fatal(),log.Fatalln(),log.Fatalf()输出到logger.out,再执行panic():log.Panic(),log.Panicln(),log.Panicf()logger结构体typeLoggerstruc......
  • Golang - Structs 包的使用
    packagemain////主要用于struct转map//还可以判断结构体是否有空属性等功能//import( "fmt" "github.com/fatih/structs")//struct-->maptypeStustruct{ Namestring Ageint}funcmain(){ //创建一个Age属性为空的struct实例 u1:=Stu{......
  • 单片机开发HTTP网页服务器所需要网页转化16进制工具
    一、 1.单片机开发HTTP网页服务器时需要把网页数据转化成16进制数据,这样发送方便和节省硬件资源。所以开发此工具,方便使用,可以把web各种资源转化到一个文件里。程序界面如图: 二、程序使用1.把web文件放到一个文件夹下面,程序选定此文件夹。如果生成的数据需要包含Response......
  • .NET7 for LoongArch64(国产龙芯)
    目前龙芯通过自己的指令集LA64支持了.Net7.0.1版本,一同被支持的有Ruby,Nodejs,Java,Electron,Python等。原文:在此处龙芯.Net7sdk下载地址:http://ftp.loongnix.cn/tmp/dotnet/7.0.5/7.0.5-ea1/dotnet-sdk-7.0.105-ea1-loongarch64.tar.xz在.Net8里面也可见支持LA64的代码,下面......
  • .NET Compiler Platform SDK
    .NETCompilerPlatformSDK.NETCompilerPlatform是什么?通过学习该模型可以更快的了解Roslyn,或者说更快的了解c#编译器的相关知识。编译器管道编译器管道是什么如上图所示,编译器管在每个阶段会进行不同的操作,这些操作我们可以理解为一个独立的组件或者模块,是一个黑盒结构......
  • Kubernetes——构建平台工程的利器
    作者|LoftTeam翻译|Seal软件链接|https://loft.sh/blog/why-platform-engineering-teams-should-standardize-on-kubernetes/ 在当今快节奏、不断变化的技术环境中,平台工程团队一直面临着交付新的创新解决方案以满足不断变化的业务需求的压力。最大挑战之一则是管理支持这些......
  • 安全的HTTP相应头
    21.1默认安全头SpringSecurity允许用户轻松注入默认安全标头以帮助保护他们的应用程序。SpringSecurity默认包含以下标头:缓存控制:无缓存,无存储,最大年龄=0,必须重新验证Pragma:无缓存过期:0X-Content-Type-Options:nosniffStrict-Transport-Security:max-age=31......
  • 安装部署 Kubernetes 仪表板(Dashboard)
    简介Kubernetes仪表板(Dashboard)是基于网页的Kubernetes用户界面。你可以使用仪表板:展示了Kubernetes集群中的资源状态信息和所有报错信息。把容器应用部署到Kubernetes集群中。对容器应用排错。管理集群资源。获取运行在集群中的应用的概览信息。创建或者修改Kub......
  • Neutral Network Notes
    TableofContents卷积Let'sgetstarted卷积1.卷积公式\[\int_{-\infty}^{+\infty}f(\tau)g(x-\tau)d\tau\]2.卷积公式的理解   符号意义\(f(t)\)\(t\)时刻的进食量\(\int_{0}^{t}f(t)dt\)截止\(t\)时刻的总进食量\(g(t)\)某一时刻进食......
  • ASP.NET Core Identity 系列之二
    转自:https://mp.weixin.qq.com/s?__biz=MzA3NDM1MzIyMQ==&mid=2247486148&idx=1&sn=dae55b414e123c6718e470c21c8c8c21桂迹,微信公众号这节我们主要演示在ASP.NETCoreIdentity中创建、修改、删除、查询用户1.ASP.NETCoreIdentityUserManager类UserManager类位于Microsof......