【golang】实现通用的get/post请求(接受一个 URL 和一个结构体参数)

通用的GET请求

实现一个通用的 GET 请求函数,该函数接受一个 URL 和一个结构体参数,并将结构体参数编码为查询参数。以下是一个通用的示例代码:

go 复制代码
package main

import (
	"fmt"
	"net/http"
	"net/url"
	"reflect"
	"strings"
)

func getFunc(baseUrl string, structParam interface{}) {
	// 创建查询参数
	queryParams := url.Values{}
	v := reflect.ValueOf(structParam)
	t := v.Type()

	// 遍历结构体字段,将字段名和值添加到查询参数
	for i := 0; i < v.NumField(); i++ {
		field := t.Field(i)
		value := v.Field(i)

		// 使用 struct 标签中的 "query" 值作为查询参数的键名
		queryKey := field.Tag.Get("query")
		if queryKey == "" {
			// 如果没有指定查询参数的键名,则使用字段名
			queryKey = field.Name
		}

		// 将字段值转换为字符串并添加到查询参数
		queryValue := fmt.Sprintf("%v", value.Interface())
		queryParams.Add(queryKey, queryValue)
	}

	// 构建带查询参数的 URL
	urlWithParams := baseUrl + "?" + queryParams.Encode()

	req, err := http.NewRequest("GET", urlWithParams, nil)
	if err != nil {
		panic(err)
	}

	// 创建 HTTP 客户端并发送请求
	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	// 读取响应内容
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Printf("HTTP GET error: %v\n", err)
		return
	}

	// 检查响应状态码
	if resp.StatusCode == http.StatusOK {
		fmt.Println("Request successful:", string(body))
	} else {
		fmt.Printf("Request failed with status: %d\n", resp.StatusCode)
	}
}

func main() {
	// 示例结构体
	type ExampleParam struct {
		UserId    int    `query:"user_id"`
		Username  string `query:"username"`
		Page      int    `query:"page"`
		PageSize  int    `query:"page_size"`
	}

	// 调用通用 GET 请求函数
	baseURL := "https://example.com/api/endpoint"
	params := ExampleParam{
		UserId:    123456,
		Username:  "john_doe",
		Page:      1,
		PageSize:  10,
	}

	getFunc(baseURL, params)
}

上述代码中的 getFunc 函数是通用的,它接受一个 URL 和一个结构体参数,并将结构体参数的字段值编码为查询参数,然后发送 HTTP GET 请求。你可以根据需要调用 getFunc 函数,并传递不同的结构体参数和目标 URL。这使得你可以轻松地实现多个不同的 GET 请求,而不需要为每个请求都编写独立的代码。

通用的POST请求

同样,实现一个通用的 postFunc 函数,该函数接受一个 URL 和一个结构体参数,并将结构体参数编码为 JSON 数据,然后发送 HTTP POST 请求。以下是一个通用的示例代码:

go 复制代码
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/http"
)

func postFunc(baseUrl string, structParam interface{}) {
	// 将结构体参数编码为 JSON 数据
	jsonData, err := json.Marshal(structParam)
	if err != nil {
		panic(err)
	}

	// 创建 HTTP 请求
	req, err := http.NewRequest("POST", baseUrl, bytes.NewBuffer(jsonData))
	if err != nil {
		panic(err)
	}

	// 设置请求头,指定 JSON 内容类型
	req.Header.Set("Content-Type", "application/json")

	// 创建 HTTP 客户端并发送请求
	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	// 读取响应内容
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Printf("HTTP POST error: %v\n", err)
		return
	}

	// 检查响应状态码
	if resp.StatusCode == http.StatusOK {
		fmt.Println("Request successful:", string(body))
	} else {
		fmt.Printf("Request failed with status: %d\n", resp.StatusCode)
	}
}

func main() {
	// 示例结构体
	type ExampleParam struct {
		UserId   int    `json:"user_id"`
		Username string `json:"username"`
	}

	// 调用通用 POST 请求函数
	baseURL := "https://example.com/api/endpoint"
	params := ExampleParam{
		UserId:   123456,
		Username: "john_doe",
	}

	postFunc(baseURL, params)
}

上述代码中的 postFunc 函数是通用的,它接受一个 URL 和一个结构体参数,并将结构体参数的字段值编码为 JSON 数据,然后发送 HTTP POST 请求。你可以根据需要调用 postFunc 函数,并传递不同的结构体参数和目标 URL。这使得你可以轻松地实现多个不同的 POST 请求,而不需要为每个请求都编写独立的代码。

相关推荐
朝朝辞暮i2 小时前
C++ 第 23 课:class —— 开始真正进入面向对象
开发语言·c++·算法
小师兄吃牛肉3 小时前
C语言篇:宏
c语言·开发语言
郑同学的笔记3 小时前
【c++随笔28】strcmp 和 memcmp对比
开发语言·c++
言乐63 小时前
Python根据无法识别搜索词找出可能输入内容模型
开发语言·python·django·virtualenv·pygame
weixin_307779134 小时前
有限产能智能排产与动态重排智能体:从需求解构到技术实现
开发语言·人工智能·算法·架构
kakakahahahaha4 小时前
Windows C盘临时文件清理:%temp%、Windows Temp、Prefetch、Windows.old与hiberfil.sys处理指南
c语言·开发语言·windows
朝朝辞暮i4 小时前
C++ 第 27 课:智能指针 shared_ptr
开发语言·c++·算法
朝朝辞暮i4 小时前
C++ 第 29 课:回调函数 Callback
开发语言·c++·算法
笨笨饿4 小时前
140_AI新手村MCP与Skills是干嘛的
开发语言·人工智能·python·stm32·单片机·嵌入式硬件·物联网
YOLO数据集集合5 小时前
EvoAgent:面向PR研发治理的自进化Multi-Agent Harness系统
java·开发语言·目标检测·agent·自进化