【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 请求,而不需要为每个请求都编写独立的代码。

相关推荐
杜子不疼.15 分钟前
【C++ 在线五子棋对战】- 会话管理模块实现
开发语言·c++
有点。19 分钟前
C++深度优先搜索(DFS)的概念(一)
开发语言·c++·深度优先
时间的拾荒人25 分钟前
C语言编译与链接:从源码到可执行程序的完整解析
c语言·开发语言
人道领域26 分钟前
【0-1的agent进阶篇】Prompt 与上下文工程
java·开发语言·prompt·mcp
aaPIXa62227 分钟前
C++大型项目模块化拆分实战记录
开发语言·c++
z落落30 分钟前
C# WinForm 线程池与事件等待+进度条暂停恢复实战案例
开发语言·c#
石山代码35 分钟前
C++23 新特性在 CLion 中的实战体验
开发语言·c++·c++23
浮江雾36 分钟前
Flutter第四节------核心概念学习笔记:从基础语法到异步编程
linux·服务器·开发语言·笔记·flutter·入门·基础
北冥you鱼1 小时前
Go Modules 使用指南:从入门到精通
开发语言·后端·golang
l1t1 小时前
duckdb 1.6dev新增的.manual命令
开发语言·数据库