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

通用的GET请求

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

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 请求。以下是一个通用的示例代码:

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

你可能感兴趣的:(golang,golang,开发语言,http)