多服务器程序运行
package mainimport ("fmt""github.com/gin-gonic/gin""golang.org/x/sync/errgroup""net/http""time"
)var g errgroup.Group // 使用 errgroup.Group 来并发启动这两个服务器func main() {// 服务器1server01 := &http.Server{Addr: ":9090", Handler: router01(),ReadTimeout: 5 * time.Second,WriteTimeout: 10 * time.Second,}// 服务器2server02 := &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 mainimport ("github.com/gin-gonic/gin""net/http"
)type ResGroup struct {Data stringPath string
}func main() {router := gin.Default()// 路由分组1v1 := router.Group("/v1") // /v1{// 路由分组1.1r := v1.Group("/user") // /v1/userr.GET("/login", login) // /v1/user/login// // 路由分组1.1.1r2 := r.Group("showInfo") // /v1/user/showInfor2.GET("/abstract", abstract) // /v1/user/showInfo/abstractr2.GET("/detail", detail) // /v1/user/showInfo/detail}// 路由分组2v2 := 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
- user
- v2
- other
gin框架 bind
package mainimport ("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 Loginerr := 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 mainimport ("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 ClientRequestvar response ClientResponseerr := context.Bind(&requestData) // 绑定请求数据if err != nil {response.Code = http.StatusBadRequestresponse.Msg = "请求的参数错误"response.Data = errcontext.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 TempDatajson.Unmarshal(data, &temp) // 反序列化response.Code = http.StatusOKresponse.Msg = "请求数据成功"response.Data = tempcontext.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
}