【Java转Go】快速上手学习笔记(七)之网络编程篇二(Gin)

Gin使用的相关笔记。

老规矩,我们要用Gin,那就得先去下载:

go get github.com/gin-gonic/gin

启动gin应用程序

func main() {
    
    
	// 创建一个gin路由
	router := gin.Default()
	// 设置请求的接口地址
	router.GET("/ping", ping)
	router.GET("/get1", get)
	router.GET("/get2/:name", get) // 通过占位符 : 指定路径参数名为 name
	//router.GET("/get2/*name", get) // 通过占位符 * 指定路径参数名为 name
	router.POST("/post", post)
	router.PUT("/put", put)
	//router.DELETE("/delete", Delete)
	router.DELETE("/delete/:id", Delete) // 通过id删除数据
	router.GET("/head", head)
	router.POST("/file", file)
	// 启动gin应用程序,设置端口号
	router.Run(":7070")
}

统一的返回参数格式

// 统一的返回参数格式
type Result struct {
    
    
	Code    int    // 统一的返回码,0 成功 -1 失败
	Message string // 统一的返回信息
	Data    any    // 统一的返回数据
}

统一的处理响应数据

// 处理响应数据
func handleRes(res *http.Response, err error) {
    
    
	if err != nil {
    
    
		fmt.Println("请求失败")
	}
	defer res.Body.Close()
	b, err := io.ReadAll(res.Body)
	if err != nil {
    
    
		fmt.Println("获取返回数据错误", err)
		return
	}
	fmt.Println(string(b))
}

GET 请求

发起get请求

func get请求() {
    
    
	// 如果只是想对一个url发起一个get请求,不带任何头部信息,那么http.Get方法就非常适合
	//http.Get("http://127.0.0.1:7070/ping")
	res, err := http.Get("http://127.0.0.1:7070/get1?name=符华&password=123456")
	//res, err := http.Get("http://127.0.0.1:7070/get2/符华")
	handleRes(res, err)
}

接收

// get 请求,通过 ? 号拼接,或者是 url 路径参数
func get(c *gin.Context) {
    
    
	fmt.Println("这里是一个get请求呀~")
	// 1、get请求中,通过问号拼接传过来的参数,用 Query("参数名")
	fmt.Println(c.Query("name"), c.Query("password"))
	// DefaultQuery 和 Query 的区别就是多了一个默认值
	//fmt.Println(c.DefaultQuery("name","默认值"), c.DefaultQuery("password","默认值"))

	// 2、get请求中,url 路径参数接收,用 Param("路由中指定的参数名")
	//fmt.Println(c.Param("name"))

	// 使用 gin.H 返回
	//c.JSON(http.StatusOK, gin.H{"code": 0, "message": "请求成功", "data": nil})
	// 如果是想要用统一的自定义返回格式,需要使用 JSONP :将给定的结构体作为JSON序列化到响应体中。
	c.JSONP(http.StatusOK, Result{
    
    0, "get请求成功", nil}) // 使用自定义的统一返回参数格式
}

POST 请求

发起post请求

这里 form-data 和 x-www-form-urlencoded 格式的区别大概是 form-data 可以传文件

func post请求() {
    
    
	// post请求,一般有 json格式、 form-data格式 和 x-www-form-urlencoded 格式
	//param := url.Values{}
	//param.Add("name", "符华")
	//param.Add("password", "123456")
	// application/x-www-form-urlencoded
	//res, err := http.PostForm("http://127.0.0.1:7070/post", param)

	// application/json
	params := bytes.NewBuffer([]byte(`{"name": "赤鸢", "password": "chiyuan@123456"}`))
	res, err := http.Post("http://127.0.0.1:7070/post", "application/json", params)

	handleRes(res, err)
}

接收

// post 请求,application/x-www-form-urlencoded、application/json
func post(c *gin.Context) {
    
    
	fmt.Println("这里是一个post请求呀~")
	// 1、请求类型是 application/x-www-form-urlencoded,通过 PostForm 获取
	//fmt.Println(c.PostForm("name"), c.PostForm("password"))

	// 将参数绑定结构体
	//u := User{} // 初始化对象
	//err := c.ShouldBind(&u) // 通过 ShouldBind 函数,将请求参数绑定到 struct 对象。
	//if err != nil {
    
    
	//	c.JSONP(http.StatusOK, Result{0, "数据绑定失败", nil})
	//	return
	//}
	//fmt.Println(u)

	// 2、请求类型是 application/json,通过 GetRawData 获取
	//data, err := c.GetRawData()
	//if err != nil {
    
    
	//	c.JSONP(http.StatusOK, Result{-1, "获取请求数据错误", nil}) // 使用自定义的统一返回参数格式
	//	return
	//}
	//fmt.Println(string(data))

	// 将参数绑定结构体
	var u User
	//err := c.BindJSON(&u) // 通过 BindJSON 函数,将请求参数绑定到 struct 对象。
	err := c.ShouldBindJSON(&u) // 通过 ShouldBindJSON 函数,将请求参数绑定到 struct 对象。
	if err != nil {
    
    
		c.JSONP(http.StatusOK, Result{
    
    0, "数据绑定失败", nil})
		return
	}
	fmt.Println(u)
	c.JSONP(http.StatusOK, Result{
    
    0, "post请求成功", nil}) // 使用自定义的统一返回参数格式
}

PUT 请求

发起put请求

func put请求() {
    
    
	params := `{"name": "赤鸢", "password": "chiyuan@123456"}`
	req, _ := http.NewRequest("PUT", "http://localhost:7070/put", strings.NewReader(params))
	res, err := http.DefaultClient.Do(req)
	handleRes(res, err)
}

接收

// put 请求,json格式
func put(c *gin.Context) {
    
    
	fmt.Println("这里是一个put请求呀~")
	// 将参数绑定结构体
	var u User
	//err := c.BindJSON(&u) // 通过 BindJSON 函数,将请求参数绑定到 struct 对象。
	err := c.ShouldBindJSON(&u) // 通过 ShouldBindJSON 函数,将请求参数绑定到 struct 对象。
	if err != nil {
    
    
		c.JSONP(http.StatusOK, Result{
    
    0, "数据绑定失败", nil})
		return
	}
	fmt.Println(u)
	c.JSONP(http.StatusOK, Result{
    
    0, "put请求成功", nil}) // 使用自定义的统一返回参数格式
}

DELETE 请求

发起delete请求

func delete请求() {
    
    
	// 批量删除,json 格式,多个id用逗号隔开
	//params := `{"id": "1,2,3"}`
	//req, _ := http.NewRequest("DELETE", "http://localhost:7070/delete", strings.NewReader(params))
	// 单个删除,直接用路径模式
	req, _ := http.NewRequest("DELETE", "http://localhost:7070/delete/1", nil)
	res, err := http.DefaultClient.Do(req)
	handleRes(res, err)
}

接收

// delete 请求,json格式和路径模式
func Delete(c *gin.Context) {
    
    
	fmt.Println("这里是一个delete请求呀~")
	// json 格式
	//data, err := c.GetRawData()
	//if err != nil {
    
    
	//	c.JSONP(http.StatusOK, Result{-1, "获取请求数据错误", nil})
	//	return
	//}
	//var j map[string]string
	//err = json.Unmarshal(data, &j) // 将json字符串转为map
	//if err != nil {
    
    
	//	fmt.Println(err)
	//	c.JSONP(http.StatusOK, Result{-1, "数据转换错误", nil})
	//	return
	//}
	//ids := j["id"]
	//arr := strings.Split(ids, ",") // 根据逗号,将字符串分割成数组
	//fmt.Println("需要删除的id", arr)

	// 路径模式
	fmt.Println("需要删除的id", c.Param("id"))

	c.JSONP(http.StatusOK, Result{
    
    0, "delete请求成功", nil})
}

HEAD 请求头

设置head请求头

/*
Set和Add的区别:
	Set:如果这一项已存在,后面的就修改已有的。
	Add:如果不存在,则添加;如果已存在,就再追加一个。
*/
func head传参() {
    
    
	req, _ := http.NewRequest("GET", "http://127.0.0.1:7070/head", nil)
	//req.Header.Set("name", "符华")
	//req.Header.Set("name", "赤鸢") // 这里会修改前面设置的name的值
	//req.Header.Add("name", "云墨") // name已存在,会追加

	req.Header.Add("name", "符华")
	req.Header.Set("name", "炽翎") // 这里会修改前面设置的name的值
	res, err := http.DefaultClient.Do(req)
	handleRes(res, err)
}

接收

// 接收head请求头参数
func head(c *gin.Context) {
    
    
	byteData, err := json.Marshal(c.Request.Header)
	fmt.Println(string(byteData), err)
	c.JSONP(http.StatusOK, Result{
    
    0, "head传参成功", nil})
}

file 文件上传

上传文件

func file上传() {
    
    
	// 读取文件
	file, err := os.Open("C:\\Users\\Administrator\\Desktop\\1.png")
	if err != nil {
    
    
		fmt.Println(err)
		return
	}
	defer file.Close()
	// 创建缓冲区,存储文件数据
	bodyBuf := &bytes.Buffer{
    
    }
	bodyWrite := multipart.NewWriter(bodyBuf)
	// 创建文件表单字段
	fileWrite, err := bodyWrite.CreateFormFile("file", "1.png")
	// 将文件内容拷贝到表单字段中
	_, err = io.Copy(fileWrite, file)
	if err != nil {
    
    
		log.Println("err")
		return
	}
	// 必须在写入文件之后关闭 writer,以写入结尾标记
	bodyWrite.Close()
	// 设置 ContentType 为 multipart/form-data; boundary=
	contentType := bodyWrite.FormDataContentType()
	// 创建 HTTP 请求
	res, err := http.Post("http://127.0.0.1:7070/file", contentType, bodyBuf)
	handleRes(res, err)
}

接收

// 接收file参数
func file(c *gin.Context) {
    
    
	fileHeader, err := c.FormFile("file")
	if err != nil {
    
    
		return
	}
	fmt.Println(fileHeader.Filename)
	c.SaveUploadedFile(fileHeader, "upload/"+fileHeader.Filename)
	c.JSONP(http.StatusOK, Result{
    
    0, "file上传成功", nil})
}

完整代码

服务端

package main

import (
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
	"net/http"
)

// 统一的返回参数格式
type Result struct {
    
    
	Code    int    // 统一的返回码,0 成功 -1 失败
	Message string // 统一的返回信息
	Data    any    // 统一的返回数据
}

// 用户结构体
type User struct {
    
    
	Name     string `json:"name" form:"name"`
	Password string `json:"password" form:"password"`
}

func ping(c *gin.Context) {
    
    
	fmt.Println("成功请求")
}

// get 请求,通过 ? 号拼接,或者是 url 路径参数
func get(c *gin.Context) {
    
    
	fmt.Println("这里是一个get请求呀~")
	// 1、get请求中,通过问号拼接传过来的参数,用 Query("参数名")
	fmt.Println(c.Query("name"), c.Query("password"))
	// DefaultQuery 和 Query 的区别就是多了一个默认值
	//fmt.Println(c.DefaultQuery("name","默认值"), c.DefaultQuery("password","默认值"))

	// 2、get请求中,url 路径参数接收,用 Param("路由中指定的参数名")
	//fmt.Println(c.Param("name"))

	// 使用 gin.H 返回
	//c.JSON(http.StatusOK, gin.H{"code": 0, "message": "请求成功", "data": nil})
	// 如果是想要用统一的自定义返回格式,需要使用 JSONP :将给定的结构体作为JSON序列化到响应体中。
	c.JSONP(http.StatusOK, Result{
    
    0, "get请求成功", nil}) // 使用自定义的统一返回参数格式
}

// post 请求,application/x-www-form-urlencoded、application/json
func post(c *gin.Context) {
    
    
	fmt.Println("这里是一个post请求呀~")
	// 1、请求类型是 application/x-www-form-urlencoded,通过 PostForm 获取
	//fmt.Println(c.PostForm("name"), c.PostForm("password"))

	// 将参数绑定结构体
	//u := User{} // 初始化对象
	//err := c.ShouldBind(&u) // 通过 ShouldBind 函数,将请求参数绑定到 struct 对象。
	//if err != nil {
    
    
	//	c.JSONP(http.StatusOK, Result{0, "数据绑定失败", nil})
	//	return
	//}
	//fmt.Println(u)

	// 2、请求类型是 application/json,通过 GetRawData 获取
	//data, err := c.GetRawData()
	//if err != nil {
    
    
	//	c.JSONP(http.StatusOK, Result{-1, "获取请求数据错误", nil}) // 使用自定义的统一返回参数格式
	//	return
	//}
	//fmt.Println(string(data))

	// 将参数绑定结构体
	var u User
	//err := c.BindJSON(&u) // 通过 BindJSON 函数,将请求参数绑定到 struct 对象。
	err := c.ShouldBindJSON(&u) // 通过 ShouldBindJSON 函数,将请求参数绑定到 struct 对象。
	if err != nil {
    
    
		c.JSONP(http.StatusOK, Result{
    
    0, "数据绑定失败", nil})
		return
	}
	fmt.Println(u)
	c.JSONP(http.StatusOK, Result{
    
    0, "post请求成功", nil}) // 使用自定义的统一返回参数格式
}

// put 请求,json格式
func put(c *gin.Context) {
    
    
	fmt.Println("这里是一个put请求呀~")
	// 将参数绑定结构体
	var u User
	//err := c.BindJSON(&u) // 通过 BindJSON 函数,将请求参数绑定到 struct 对象。
	err := c.ShouldBindJSON(&u) // 通过 ShouldBindJSON 函数,将请求参数绑定到 struct 对象。
	if err != nil {
    
    
		c.JSONP(http.StatusOK, Result{
    
    0, "数据绑定失败", nil})
		return
	}
	fmt.Println(u)
	c.JSONP(http.StatusOK, Result{
    
    0, "put请求成功", nil}) // 使用自定义的统一返回参数格式
}

// delete 请求,json格式和路径模式
func Delete(c *gin.Context) {
    
    
	fmt.Println("这里是一个delete请求呀~")
	// json 格式
	//data, err := c.GetRawData()
	//if err != nil {
    
    
	//	c.JSONP(http.StatusOK, Result{-1, "获取请求数据错误", nil})
	//	return
	//}
	//var j map[string]string
	//err = json.Unmarshal(data, &j) // 将json字符串转为map
	//if err != nil {
    
    
	//	fmt.Println(err)
	//	c.JSONP(http.StatusOK, Result{-1, "数据转换错误", nil})
	//	return
	//}
	//ids := j["id"]
	//arr := strings.Split(ids, ",") // 根据逗号,将字符串分割成数组
	//fmt.Println("需要删除的id", arr)

	// 路径模式
	fmt.Println("需要删除的id", c.Param("id"))

	c.JSONP(http.StatusOK, Result{
    
    0, "delete请求成功", nil})
}

// 接收head请求头参数
func head(c *gin.Context) {
    
    
	byteData, err := json.Marshal(c.Request.Header)
	fmt.Println(string(byteData), err)
	c.JSONP(http.StatusOK, Result{
    
    0, "head传参成功", nil})
}

// 接收file参数
func file(c *gin.Context) {
    
    
	fileHeader, err := c.FormFile("file")
	if err != nil {
    
    
		return
	}
	fmt.Println(fileHeader.Filename)
	c.SaveUploadedFile(fileHeader, "upload/"+fileHeader.Filename)
	c.JSONP(http.StatusOK, Result{
    
    0, "file上传成功", nil})
}

func main() {
    
    
	// 创建一个gin路由
	router := gin.Default()
	// 设置请求的接口地址
	router.GET("/ping", ping)
	router.GET("/get1", get)
	router.GET("/get2/:name", get) // 通过占位符 : 指定路径参数名为 name
	//router.GET("/get2/*name", get) // 通过占位符 * 指定路径参数名为 name
	router.POST("/post", post)
	router.PUT("/put", put)
	//router.DELETE("/delete", Delete)
	router.DELETE("/delete/:id", Delete) // 通过id删除数据
	router.GET("/head", head)
	router.POST("/file", file)
	// 启动gin应用程序,设置端口号
	router.Run(":7070")
}

客户端

package main

import (
	"bytes"
	"fmt"
	"io"
	"log"
	"mime/multipart"
	"net/http"
	"os"
	"strings"
)

// 处理响应数据
func handleRes(res *http.Response, err error) {
    
    
	if err != nil {
    
    
		fmt.Println("请求失败")
	}
	defer res.Body.Close()
	b, err := io.ReadAll(res.Body)
	if err != nil {
    
    
		fmt.Println("获取返回数据错误", err)
		return
	}
	fmt.Println(string(b))
}

func main() {
    
    
	//get请求()
	//post请求()
	//put请求()
	//delete请求()
	//head传参()
	//file上传()
}

func get请求() {
    
    
	// 如果只是想对一个url发起一个get请求,不带任何头部信息,那么http.Get方法就非常适合
	//http.Get("http://127.0.0.1:7070/ping")
	res, err := http.Get("http://127.0.0.1:7070/get1?name=符华&password=123456")
	//res, err := http.Get("http://127.0.0.1:7070/get2/符华")
	handleRes(res, err)
}

func post请求() {
    
    
	// post请求,一般有 json格式、 form-data格式 和 x-www-form-urlencoded 格式
	//param := url.Values{}
	//param.Add("name", "符华")
	//param.Add("password", "123456")
	// application/x-www-form-urlencoded
	//res, err := http.PostForm("http://127.0.0.1:7070/post", param)

	// application/json
	params := bytes.NewBuffer([]byte(`{"name": "赤鸢", "password": "chiyuan@123456"}`))
	res, err := http.Post("http://127.0.0.1:7070/post", "application/json", params)

	handleRes(res, err)
}

func put请求() {
    
    
	params := `{"name": "赤鸢", "password": "chiyuan@123456"}`
	req, _ := http.NewRequest("PUT", "http://localhost:7070/put", strings.NewReader(params))
	res, err := http.DefaultClient.Do(req)
	handleRes(res, err)
}

func delete请求() {
    
    
	// 批量删除,json 格式,多个id用逗号隔开
	//params := `{"id": "1,2,3"}`
	//req, _ := http.NewRequest("DELETE", "http://localhost:7070/delete", strings.NewReader(params))
	// 单个删除,直接用路径模式
	req, _ := http.NewRequest("DELETE", "http://localhost:7070/delete/1", nil)
	res, err := http.DefaultClient.Do(req)
	handleRes(res, err)
}

/*
Set和Add的区别:

	Set:如果这一项已存在,后面的就修改已有的。
	Add:如果不存在,则添加;如果已存在,就再追加一个。
*/
func head传参() {
    
    
	req, _ := http.NewRequest("GET", "http://127.0.0.1:7070/head", nil)
	//req.Header.Set("name", "符华")
	//req.Header.Set("name", "赤鸢") // 这里会修改前面设置的name的值
	//req.Header.Add("name", "云墨") // name已存在,会追加

	req.Header.Add("name", "符华")
	req.Header.Set("name", "炽翎") // 这里会修改前面设置的name的值
	res, err := http.DefaultClient.Do(req)
	handleRes(res, err)
}

func file上传() {
    
    
	// 读取文件
	file, err := os.Open("C:\\Users\\Administrator\\Desktop\\1.png")
	if err != nil {
    
    
		fmt.Println(err)
		return
	}
	defer file.Close()
	// 创建缓冲区,存储文件数据
	bodyBuf := &bytes.Buffer{
    
    }
	bodyWrite := multipart.NewWriter(bodyBuf)
	// 创建文件表单字段
	fileWrite, err := bodyWrite.CreateFormFile("file", "1.png")
	// 将文件内容拷贝到表单字段中
	_, err = io.Copy(fileWrite, file)
	if err != nil {
    
    
		log.Println("err")
		return
	}
	// 必须在写入文件之后关闭 writer,以写入结尾标记
	bodyWrite.Close()
	// 设置 ContentType 为 multipart/form-data; boundary=
	contentType := bodyWrite.FormDataContentType()
	// 创建 HTTP 请求
	res, err := http.Post("http://127.0.0.1:7070/file", contentType, bodyBuf)
	handleRes(res, err)
}

ok,以上就是本篇笔记的全部内容了。

猜你喜欢

转载自blog.csdn.net/weixin_43165220/article/details/132516062