0. 为什么会有Go
1. 环境搭建
初始项目
go mod init 目前文件夹名
下载:
go get -u github.com/gin-gonic/gin
2. 单-请求&&返回-样例
这样我们的服务就可以跑起来了哈
此时提供给了前端GET请求的/hello路由,GET后面的函数就是我们对此请求的处理(返回给前端)
package main
//导入gin
import (
"github.com/gin-gonic/gin"
)
func main(){
//创建一个服务
ginServer := gin.Default()
//访问地址,处理我们的请求 Request Response
ginServer.GET("/hello", func(context/*理解为我们上下文接收请求或者响应数据*/ *gin.Context) {
/*我们所有的信息使用gin的默认对象包裹*/
context.JSON(200,gin.H{"message":"hello world"})
})
//服务器端口
ginServer.Run(":9090")/*默认是8080*/
}
(这个插件是之前提过的哈)
或者直接访问
3. RESTful API
然后我们现在写一个 RESTful API
3.1 首先什么是RESTful API
以前写网站:
比如查询用户就是:get /user
创建一个用户就是:post /create_user
又或者更新用户就是:post /update_user
又或者删除用户就是:post /delete_user
RESTful API 就是通过不同的请求执行不同的功能,以前我们是通过url和请求来隔离,现在我们可以通过四种方式来隔离,比如:
查询用户:get /user
提交用户:post /user
修改用户:put /user(这个就变了,不是post)
删除用户:delete /user
就是我们同一个请求(/user)用不同的方式(get post put),会执行不同的方法,这就是RESTful API
3.2 Gin框架支持RESTful API的开发
所以我们的代码就可以变成:
我们就发现 Go语言+Gin框架 去开发 RESTful API 是非常简单的
(但是注意,有这些方法之后,浏览器就测试不了了,因为浏览器只会使用GET方法,就需要用到上面的工具了)
然后我们现在重新(不要上一个图的东西)写一个请求然后返回前端页面的代码
4. 返回前端代码
go.main
package main
//导入gin
import (
"github.com/gin-gonic/gin"
)
func main() {
//创建一个服务
ginServer := gin.Default()
//加载前端页面
//加载所有的html文件,还有一个是加载特定的文件LoadHTMLFiles
//就是ginServer.LoadHTMLFiles("templates/index.html")
ginServer.LoadHTMLGlob("templates/*")
//访问地址,处理我们的请求 Request Response
ginServer.GET("/index", func(context *gin.Context) {
//context.JSON(200,gin.H{"message":"hello world"}) 返回json数据
//可以HTML查看定义,第一个是状态码,第二个是返回的文件名,第三个是想给文件传的参数
//数据传送都是用框架的.H方法(map集合),H的定义也就是key value,所以可以传多个参数
context.HTML(200, "index.html", gin.H{
"msg": "这是后端传来的数据",
}) //返回html数据
})
//服务器端口
ginServer.Run(":9090") /*默认是8080*/
}
index.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>个人主页</title>
</head>
<body>
<h1>欢迎来到我的个人主页</h1>
获取后端的数据为:
{{.msg}}
</body>
</html>
5. 添加静态文件
现在我们还可以在网站里面加一些静态文件
.
├── go.mod
├── go.sum
├── main.go
├── static
│ ├── css
│ │ └── style.css
│ └── js
│ └── common.js
└── templates
└── index.html
main.go 改动的地方
index.html 改动的地方
style.css 改动的地方
common.js 改动的地方
6. 获取请求中的参数
6.1 传统的传参
6.2 RESTful API 方式传参与接收
6.3 前端传递Json数据给后端
6.4 前端返回的是表单
在index.html添加表单
在main.go里面添加特定请求的放法
7. 关于重定向
注意重定向的状态码不是200
7.1 重定向到网页
main.go
7.2 404
main.go
添加404.html,让重定向去跳转
7.3 路由组
路由组就是我们可以统一管理路由,比如跟/user相关的所有路由,我们都放在这个里面
main.go
8. 中间件(java里面的拦截器)
中间件就是比如前端发送一个请求到/user/add,然后这个请求就到我们后端来处理了,但是我现在想这个请求没有到我的程序之前加一道防火墙,在拦截的地方预处理这个请求,这就是go的中间件。(一般这个预处理我们就会进行比如登录的验证,授权,分页,耗时统计...)
我们现在自己来实现一个中间件:
然后我们来使用:
现在我们在这里多加了一个中间件的函数,让我们调用这个方法的时候,先让myHandler去处理
如果中间件进行拦截,就会返回这个
9. 总代码
main.go
package main
//导入gin
import (
"encoding/json"
"log"
"net/http"
"github.com/gin-gonic/gin"
)
func myHandler() gin.HandlerFunc {
return func(context *gin.Context) {
//通过自定义的中间件,设置的值,后续处理只要调用了这个中间件
//的都可以拿到这个值
context.Set("usersesion", "userid-1")
//拦截器无非就两个方法,一个是放过一个是拦截
if true {
context.Next() //放行
}
context.Abort() //阻止
}
}
func main() {
//创建一个服务
ginServer := gin.Default()
//注册中间件
//如果没有指定特定请求方法,那么就是所有方法都使用,指定了就是特定的
ginServer.Use(myHandler())
//加载前端页面
//加载所有的html文件,还有一个是加载特定的文件LoadHTMLFiles
//就是ginServer.LoadHTMLFiles("templates/index.html")
ginServer.LoadHTMLGlob("templates/*")
//跳转到这里,然后加载资源文件 static是前端文件夹,./static是文件夹的路径
ginServer.Static("/static", "./static")
//访问地址,处理我们的请求 Request Response
ginServer.GET("/index", func(context *gin.Context) {
//context.JSON(200,gin.H{"message":"hello world"}) 返回json数据
//可以HTML查看定义,第一个是状态码,第二个是返回的文件名,第三个是想给文件传的参数
//数据传送都是用框架的.H方法(map集合),H的定义也就是key value,所以可以传多个参数
context.HTML(200, "index.html", gin.H{
"msg": "这是后端传来的数据",
}) //返回html数据
})
//获取请求中的参数
//传统的传参方法:url?userid=xxx&username=xxx
//请求-处理请求的函数,这个格式是固定的
ginServer.GET("/user/info", myHandler(), func(context *gin.Context) {
//加入中间件之后,开始说了调用的函数都可以取到中间件的值,现在我们取他
//看源码返回的是any,我们转成string
usersesion := context.MustGet("usersesion").(string)
log.Println("==============>", usersesion)
userid := context.Query("userid")
username := context.Query("username")
context.JSON(http.StatusOK, gin.H{
"userid": userid,
"username": username,
})
})
//RESTful传参方法:/url/info/1/xxx
ginServer.GET("/user/info/:userid/:username", func(context *gin.Context) {
userid := context.Param("userid")
username := context.Param("username")
context.JSON(http.StatusOK, gin.H{
"userid": userid,
"username": username,
})
})
//前端给后端传递 json数据
ginServer.POST("/json", func(context *gin.Context) {
//从 request.body中获取json数据
//[]byte是字节切片,是一个二进制数据,可以理解为一个字符串
b, _ := context.GetRawData()
var m map[string]interface{}
//切片b转换成map
_ = json.Unmarshal(b, &m)
context.JSON(http.StatusOK, m)
})
ginServer.POST("/user/add", func(context *gin.Context) {
username := context.PostForm("username")
password := context.PostForm("password")
context.JSON(http.StatusOK, gin.H{
"msg": "ok",
"username": username,
"password": password,
})
})
//关于重定向
ginServer.GET("/redirect", func(context *gin.Context) {
//重定向到百度
context.Redirect(http.StatusMovedPermanently, "http://www.baidu.com")
})
//404 就是 NoRoute
ginServer.NoRoute(func(context *gin.Context) {
context.HTML(http.StatusNotFound, "404.html", nil)
})
userGroup := ginServer.Group("/user")
{
//我们去网页访问的时候,就想当关于 /user/list
userGroup.GET("/list", func(context *gin.Context) {
context.JSON(http.StatusOK, gin.H{
"msg": "获取用户列表",
})
//我们去网页访问的时候,就想当关于 /user/info
userGroup.POST("/info", func(context *gin.Context) {
context.JSON(http.StatusOK, gin.H{
"msg": "获取用户信息",
})
})
})
}
//服务器端口
ginServer.Run(":9090") /*默认是8080*/
}
templates/index.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>个人主页</title>
<!--引入静态文件,css是link-->
<link rel="stylesheet" href="/static/css/style.css">
<!--引入静态文件,js是script-->
<script src="/static/js/common.js"></script>
<!--但是并不是引用了就能直接用,现在跳转到main.go中-->
</head>
<body>
<h1>欢迎来到我的个人主页</h1>
获取后端的数据为:
{{.msg}}
<!--这就是个提交表单,提交之后就会让后端处理这个请求-->>
<form action="/user/add" method="post">
<p>用户名:<input type="text" name="username"></p>
<p>密码:<input type="password" name="password"></p>
<p><input type="submit" value="提交"></p>
</form>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>404 Not Found</title>
<style>
body {
font-family: Arial, sans-serif;
text-align: center;
background-color: #f0f0f0;
}
h1 {
font-size: 6em;
color: #333;
margin-top: 20vh;
}
p {
font-size: 1.5em;
color: #666;
}
a {
color: #007bff;
text-decoration: none;
}
</style>
</head>
<body>
<h1>404</h1>
<p>Oops! The page you're looking for could not be found.</p>
<p>Go back to <a href="/">homepage</a>.</p>
</body>
</html>
static/css
style.css
body{
background:aqua;
/*让背景颜色变成蓝色*/
}
common.css
狂神YYDS!!!
创作不易,希望读者三连支持 💖
赠人玫瑰,手有余香 💖
版权归原作者 原来45 所有, 如有侵权,请联系我们删除。