今天是第六届青训营笔记打卡的第四天 本文主要内容是Gin框架学习的部分内容,主要包括以下三个方面 :
- 安装go和gin框架
- Gin的初体验
- Gin框架对各种XX的响应
安装go和gin
安装go
下载网址 :
直接将解压的bin添加到环境目录即可
验证go环境
go version
编写一个hello.go的文件,文件内容为
package main
import "fmt"
func main() {
fmt.Println("Hello, World!")
}
通过编译器运行go文件
go run hello.go
如果出现“Hello World!”就说明运行成功了,当然,我们肯定需要一个趁手的IDE工具才行
goland编辑器下载
www.jetbrains.com/go/download…
和pycharm的安装方式类似
配置代理
在使用go的时候,会需要安装一些第三方包
如果不配置代理,那么则会从go的官网上去拉取第三方包
GOPROXY=https://goproxy.cn,direct
安装gin
在终端输入 :
go get github.com/gin-gonic/gin
就会自动获取gin;
Gin的初体验
Hello World
编程学习到新东西第一件事 就是 "Hello World"
代码 :
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func Index(context *gin.Context) {
context.String(200, "Hello World")
}
func main() {
// 创建一个默认的路由
router := gin.Default()
// 绑定路由规则和路由函数,访问/index的路由,将由对应的函数去处理
router.GET("/index", Index)
// 启动监听,gin会把web服务器运行在本机的8080端口上
// 启动方式一 :
router.Run(":8080")
// 启动方式二 : 原生http服务的方式
http.ListenAndServe(":8080", router)
}
代码详解 :
router:=gin.Default():这是默认的服务器。使用gin的Default方法创建一个路由Handler;- 然后通过Http方法绑定路由规则和路由函数。不同于
net/http库的路由函数,gin进行了封装,把request和response都封装到了gin.Context的上下文环境中。 - 最后启动路由的Run方法监听端口。还可以用
http.ListenAndServe(":8080", router),或者自定义Http服务器配置。
注意 : 在8080前面一定要加上 : 。
GO中GET方法的具体实现 :
// GET is a shortcut for router.Handle("GET", path, handlers).
func (group *RouterGroup) GET(relativePath string, handlers ...HandlerFunc) IRoutes {
return group.handle(http.MethodGet, relativePath, handlers)
}
Go中ListenAndServer的具体实现 :
func ListenAndServe(addr string, handler Handler) error {
server := &Server{Addr: addr, Handler: handler}
return server.ListenAndServe()
}
gin的两种启动方式 :
// 启动方式一 :
router.Run(":8080")
// 启动方式二 :
http.ListenAndServe(":8080",router)
运行
打开浏览器,在地址栏输入 :
127.0.0.1:8080
出现以下界面,就代表gin开始工作了。
将地址栏输入改为
127.0.0.1:8080/index
出现以下界面 :
成功运行程序,输出Hello World!!!
关于gin中的context,gin.Context
在 Gin 中,Context 是一个非常重要的概念,用于处理 HTTP 请求和响应。在 Gin 的处理流程中,Context 贯穿整个处理过程,用于传递请求和响应的信息。
在 Gin 中,Context 是一个非常重要的概念,用于处理 HTTP 请求和响应。在 Gin 的处理流程中,Context 贯穿整个处理过程,用于传递请求和响应的信息。
Gin 的 Context 是一个结构体类型,定义如下:
type Context struct {
// 定义了一些私有成员变量,用于存储请求和响应等信息
// ...
}
Context 中封装了原生的 Go HTTP 请求和响应对象,同时还提供了一些方法,用于获取请求和响应的信息、设置响应头、设置响应状态码等操作。
在 Gin 中,Context 是通过中间件来传递的。在处理 HTTP 请求时,Gin 会依次执行注册的中间件,每个中间件可以对 Context 进行一些操作,然后将 Context 传递给下一个中间件。
例如,下面是一个简单的中间件,用于在请求头中设置一个自定义的 X-Request-ID:
func RequestIDMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
requestID := generateRequestID()
c.Request.Header.Set("X-Request-ID", requestID)
c.Next() // 将 Context 传递给下一个中间件
}
}
在上面的中间件中,我们生成了一个请求 ID,然后将其设置到请求头中。接着,调用 c.Next() 方法将 Context 传递给下一个中间件。这样,下一个中间件就可以通过 c.Request.Header.Get("X-Request-ID") 获取到这个请求 ID。
总之,在 Gin 中,Context 是通过中间件来传递的。每个中间件都可以对 Context 进行一些操作,然后将其传递给下一个中间件,最终由处理函数来使用 Context 中的信息进行处理。
响应
200 表示正常响应 http.StatusOK
响应字符串
router.GET("/txt", func(c *gin.Context) {
c.String(http.StatusOK, "返回txt")
})
响应json
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func _json(c *gin.Context) {
c.JSON(200, 2)
}
func main() {
router := gin.Default()
router.GET("/json", _json)
router.Run(":80")
}
运行效果 :
响应结构体,map,和直接响应json :
func _json(c *gin.Context) {
json响应结构体
type Userinfo struct {
UserName string `json:"user_name"`
Age int `json:"age"`
PassWord string `json:"-"` // 打 '-' 表示忽略转化为json
}
user := Userinfo{"大黄", 8, "123456"}
c.JSON(200, Userinfo)
// json响应map
//userMap := map[string]string{
// "user_name": "大黄",
// "age": "8",
//}
//c.JSON(200, userMap)
//直接响应json
//c.JSON(200, gin.H{"user_anme": "大黄", "age": 8})
}
运行效果 :
响应xml
func _xml(c *gin.Context) {
c.XML(200, gin.H{"user": "ys", "message": "hello", "status": http.StatusOK, "data": gin.H{"username": "大黄", "age": 8}})
}
运行效果 :
响应yaml
func _yaml(c *gin.Context) {
c.YAML(200, gin.H{"user": "ys", "message": "hello", "status": http.StatusOK, "data": gin.H{"username": "大黄", "age": 8}})
}
运行效果: 由于浏览器原因,使用postman工具;
返回html
先创建一个模板目录 :templates
使用 LoadHTMLGlob()或者LoadHTMLFiles()方法来加载模板文件,一般放在router声明后 :
// 加载模板目录下所有的模板文件router.LoadHTMLGlob("templates/*") // 表示加载templates下所有的文件
index.html文件 :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<header>
你好啊! {{.username}}
</header>
</body>
</html>
例 :
func _html(c *gin.Context) {
c.HTML(200, "index.html", gin.H{"username": "大黄"})
}
运行效果 :
注意 :
- 在模板中使用这个title,需要使用
{{ .title }} - 不同文件夹下模板名字可以相同,此时需要 LoadHTMLGlob() 加载两层模板路径。
router.LoadHTMLGlob("templates/**/*")
router.GET("/posts/index", func(c *gin.Context) {
c.HTML(http.StatusOK, "posts/index.tmpl", gin.H{
"title": "Posts",
})
c.HTML(http.StatusOK, "users/index.tmpl", gin.H{
"title": "Users",
})
})
文件响应
结构 :
// 在go中,没有相对文件的路径,只有相对于项目的路径
// 网页请求这个静态目录的前缀,第二个参数是一个目录,注意:前缀不能重复
router.StaticFS("/static", http.Dir("static/static"))
// 配置单个文件 网络请求的路由,文件的路径
router.StaticFile("/title.png", "static/hler.png")
整体代码 :
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func main() {
router := gin.Default()
// 在go中,没有相对文件的路径,只有相对于项目的路径
// 网页请求这个静态目录的前缀,第二个参数是一个目录,注意:前缀不能重复
router.StaticFS("/static", http.Dir("static/static"))
// 配置单个文件 网络请求的路由,文件的路径
router.StaticFile("/hler.png", "static/hler.png")
router.Run(":80")
}
运行效果 :
在地址栏输入 : http://127.0.0.1/hler.png
对应 :
router.StaticFile("/hler.png", "static/hler.png")
在地址栏输入 : http://127.0.0.1/static/qqh
对应 :
router.StaticFS("/static", http.Dir("static/static"))
而输入 : http://127.0.0.1/static/pwd
因为没有对pwd,txt文件进行配置,所以访问不到,这样就可以将自己不想公开的文件不能进行访问。
重定向
重定向(Redirect)就是通过各种方法将各种网络请求重新定个方向转到其它位置
router.GET("/redirect", func(c *gin.Context) {
//支持内部和外部的重定向
c.Redirect(http.StatusMovedPermanently, "http://www.baidu.com/")
})
对于重定向,我们就实现到百度的跳转吧!!!
代码 :
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
// 重定向
func _redirect(c *gin.Context) {
c.Redirect(302, "https://www.baidu.com/")
}
func main() {
router := gin.Default()
router.SetTrustedProxies([]string{"127.0.0.1"})
router.GET("/baidu", _redirect)
router.Run(":80")
}
对于
router.SetTrustedProxies([]string{"127.0.0.1"})
这一行 : 如果遇到goland里面报错 :
[GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.
那么就加上这一行,来给gin设置一个信任的ip
运行 :
在地址栏里面输入 : 127.0.0.1/baidu
就能直接跳转到百度界面了!!!
两种状态码:
- 301 Moved Permanently
被请求的资源已永久移动到新位置,并且将来任何对此资源的引用都应该使用本响应返回的若干个 URI 之一。如果可能,拥有链接编辑功能的客户端应当自动把请求的地址修改为从服务器反馈回来的地址。除非额外指定,否则这个响应也是可缓存的。
- 302 Found
请求的资源现在临时从不同的 URI 响应请求。由于这样的重定向是临时的,客户端应当继续向原有地址发送以后的请求。只有在Cache-Control或Expires中进行了指定的情况下,这个响应才是可缓存的。
如有问题,大佬们看见还请提出,我必改正, 另外,欢迎留言交流!