gin框架提高篇(三)

多服务器程序运行

package main

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"golang.org/x/sync/errgroup"
	"net/http"
	"time"
)

var g errgroup.Group // 使用 errgroup.Group 来并发启动这两个服务器

func main() {
	// 服务器1
	server01 := &http.Server{
		Addr:         ":9090", 
		Handler:      router01(),
		ReadTimeout:  5 * time.Second,
		WriteTimeout: 10 * time.Second,
	}
	// 服务器2
	server02 := &http.Server{
		Addr:         ":9092", // 别问为啥不用 91,问就是被占用了
		Handler:      router02(),
		ReadTimeout:  5 * time.Second,
		WriteTimeout: 10 * time.Second,
	}
	// 分别启动监听
	g.Go(func() error {
		return server01.ListenAndServe()
	})
	g.Go(func() error {
		return server02.ListenAndServe()
	})
	// 通过 g.Wait() 来等待它们的执行结果
	if err := g.Wait(); err != nil {
		fmt.Println("执行失败", err)
	}
}

func router01() http.Handler {
	r1 := gin.Default()
	r1.GET("/MyServer01", func(context *gin.Context) {
		context.JSON(http.StatusOK, gin.H{
			"code": http.StatusOK,
			"msg":  "服务器程序1启动成功",
		})
	})
	return r1
}

func router02() http.Handler {
	r1 := gin.Default()
	r1.GET("/MyServer02", func(context *gin.Context) {
		context.JSON(http.StatusOK, gin.H{
			"code": http.StatusOK,
			"msg":  "服务器程序2启动成功",
		})
	})
	return r1
}

在这里插入图片描述

路由组

package main

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

type ResGroup struct {
	Data string
	Path string
}

func main() {
	router := gin.Default()
	// 路由分组1
	v1 := router.Group("/v1") // /v1
	{
		// 路由分组1.1
		r := v1.Group("/user") // /v1/user
		r.GET("/login", login) // /v1/user/login
		// // 路由分组1.1.1
		r2 := r.Group("showInfo")     // /v1/user/showInfo
		r2.GET("/abstract", abstract) // /v1/user/showInfo/abstract
		r2.GET("/detail", detail)     // /v1/user/showInfo/detail
	}

	// 路由分组2
	v2 := router.Group("/v2") // v2
	{
		v2.GET("/other", other) // /v2/other
	}
	router.Run(":9090")
}

func other(context *gin.Context) {
	context.JSON(http.StatusOK, ResGroup{"detail", context.Request.URL.Path})
}

func detail(context *gin.Context) {
	context.JSON(http.StatusOK, ResGroup{"detail", context.Request.URL.Path})
}

func abstract(context *gin.Context) {
	context.JSON(http.StatusOK, ResGroup{"abstract", context.Request.URL.Path})
}

func login(context *gin.Context) {
	context.JSON(http.StatusOK, ResGroup{"login", context.Request.URL.Path})
}

在这里插入图片描述

路由结构

  • v1
    • user
      • login
      • showInfo
        • abstract
        • detail
  • v2
    • other

gin框架 bind

package main

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

type Login struct {
	UserName string `json:"user_name" binding:"required"` // 后端字段 UserName → 前端参数 user_name,必需
	Password string `json:"password" binding:"required"`
	Remark   string `json:"remark" binding:"required"`
}

func main() {
	r := gin.Default()
	r.POST("/login", func(context *gin.Context) {
		var login Login
		err := context.Bind(&login) // 执行绑定,注意参数是地址(引用),绑定的是前端传入的数据
		if err != nil {
			context.JSON(http.StatusBadRequest, gin.H{
				"msg":  "绑定失败,参数错误",
				"data": err.Error(),
			})
			return
		}
		if login.UserName == "user" && login.Password == "123456" {
			context.JSON(http.StatusBadRequest, gin.H{
				"msg":  "登陆成功",
				"data": "OK",
			})
			return
		}
		context.JSON(http.StatusBadRequest, gin.H{
			"msg":  "登陆失败",
			"data": "error",
		})
		return
	})
	r.Run(":9090")
}

在这里插入图片描述

调用 restful 接口

ps:将上一模块的代码打包成exe文件,并执行起来,注意端口冲突问题(命令:go build 文件名)

在这里插入图片描述

  • 逻辑顺序:
    • 客户端(真实) → 服务端
    • 服务端(模拟客户端) →第三方接口
    • 第三方接口→服务端(模拟客户端)
    • 服务端→客户端(真实)
package main

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

// 第三方接口字段
type UserAPI struct {
	UserName string `json:"user_name"`
	Password string `json:"password"`
	Remark   string `json:"remark"`
}

// 第三方接口返回字段封装
type TempData struct {
	Msg  string `json:"msg"`
	Data string `json:"data"`
}

// 客户端请求字段
type ClientRequest struct {
	UserName string      `json:"user_name"`
	Password string      `json:"password"`
	Remark   string      `json:"remark"`
	Other    interface{} `json:"other"`
}

// 服务端返回字段
type ClientResponse struct {
	Code int         `json:"code"`
	Msg  string      `json:"msg"`
	Data interface{} `json:"data"`
}

func main() {
	//testAPI()
	r := gin.Default()
	r.POST("/getOtherAPI", getOtherAPI)
	r.Run(":9092")
}

func getOtherAPI(context *gin.Context) {
	var requestData ClientRequest
	var response ClientResponse
	err := context.Bind(&requestData) // 绑定请求数据
	if err != nil {
		response.Code = http.StatusBadRequest
		response.Msg = "请求的参数错误"
		response.Data = err
		context.JSON(http.StatusBadRequest, response)
		return
	}
	url := "http://127.0.0.1:9090/login"
	user := UserAPI{requestData.UserName, requestData.Password, requestData.Remark}
	data, err := getRestfulAPI(url, user, "application/json")
	var temp TempData
	json.Unmarshal(data, &temp) // 反序列化
	response.Code = http.StatusOK
	response.Msg = "请求数据成功"
	response.Data = temp
	context.JSON(http.StatusOK, response)
}

//func testAPI() {
//	url := "http://127.0.0.1:9090/login"
//	user := UserAPI{"user", "123456", "说明"}
//	data, err := getRestfulAPI(url, user, "application/json")
//	fmt.Println(data, err)
//	var temp TempData
//	json.Unmarshal(data, &temp)
//	fmt.Println(temp)
//}

func getRestfulAPI(url string, data interface{}, contentType string) ([]byte, error) {
	client := &http.Client{Timeout: 5 * time.Second}                     // 创建一个http客户端示例,去请求第三方
	jsonStr, _ := json.Marshal(data)                                     // 序列化数据
	resp, err := client.Post(url, contentType, bytes.NewBuffer(jsonStr)) // 发起post请求
	if err != nil {
		fmt.Println("调用API接口出现了错误")
		return nil, err
	}
	res, err := ioutil.ReadAll(resp.Body)
	return res, err
}

在这里插入图片描述

  • 8
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值