[Web]GinWebFramework基础学习
响应
响应(Response):响应是服务器对客户端请求的回应。响应包含了状态码(表示请求是否成功,以及失败的原因)、响应头(包含一些元信息,如内容类型、设置cookie等)和响应体(包含服务器返回的数据)
import (
"github.com/gin-gonic/gin"
)
func str(context *gin.Context) {
context.String(200, "kasumi")
}
func _json(context *gin.Context) {
//type useinfo struct {
// usern string // age int //} //user := useinfo{"yaka", 18} context.JSON(200, gin.H{"name": "kasumi", "age": 18})
}
// 响应yaml/xml
func _xml(context *gin.Context) {
context.XML(200, gin.H{"name": "kasumi", "age": 18})
}
func _yaml(context *gin.Context) {
context.XML(200, gin.H{"name": "kasumi", "age": 19})
}
// 响应html
func _html(context *gin.Context) {
context.HTML(200, "index.html", gin.H{"username": "kasumi"})
}
// 文件相应
func _file(context *gin.Context) {
context.File("static/test.txt")
}
// 重定向
func _redirect(context *gin.Context) {
context.Redirect(301, "https://www.baidu.com") // 301 永久重定向 302 临时重定向
}
func main() {
router := gin.Default()
router.LoadHTMLGlob("templates/*") // 加载模板目录下 所有模板文件
//router.Static("/static", "static") // 加载静态资源
router.StaticFile("/static/test", "static/test.txt") // 加载指定文件
router.GET("/", str)
router.GET("/json", _json)
router.GET("/xml", _xml)
router.GET("/yaml", _yaml)
router.GET("/html", _html)
router.GET("/file", _file)
router.GET("/redirect", _redirect)
err := router.Run(":8089")
if err != nil {
return
}
}
请求参数
参数是请求中的一部分,用于向服务器传递额外的信息。参数可以出现在URL中(如查询参数或路径参数),也可以出现在请求体中(如表单数据或JSON数据)。参数的类型和格式取决于请求的内容类型和请求方法
查询参数
package main
import (
"fmt"
"github.com/gin-gonic/gin")
func query(context *gin.Context) {
name := context.Query("name")
age := context.Query("age")
//localhost:8089/query?name=kasumi&age=18
context.JSON(200, gin.H{"name": name, "age": age})
fmt.Println(name, age)
}
func main() {
router := gin.Default()
router.GET("/query", query)
err := router.Run(":8089")
if err != nil {
return
}
}
动态参数
// 动态参数
// 例如:http://localhost:8089/param/kasumi/22
// 动态参数是在URL中的路径参数
func param(context *gin.Context) {
name := context.Param("name")
age := context.Param("age")
context.JSON(200, gin.H{"name": name, "age": age})
}
main:router.GET("/param/:name/:age/", param)
表单 PostForm
// 表单参数是在请求体中的参数,例如:http://localhost:8089/form
// 表单参数是在请求体中的表单数据
func form(context *gin.Context) {
name := context.PostForm("name")
age := context.PostForm("age")
//context.JSON(200, gin.H{"name": name, "age": age})
context.DefaultPostForm("name", "default")
context.DefaultPostForm("age", "default")
fmt.Println(name, age)
}
main:router.POST("/form", form)
原始参数
// 原始参数是在请求体中的原始数据,例如:http://localhost:8089/raw
// 原始参数是在请求体中的原始数据
func raw(context *gin.Context) {
// 获取原始数据
data, err := context.GetRawData()
if err != nil {
return
}
contentType := context.GetHeader("Content-Type") // 获取请求头中的Content-Type
switch contentType {
case "application/json":
type jsonStruct struct {
Name string `json:"name"`
Age int `json:"age"`
}
var jsondata jsonStruct // 定义一个结构体
// 将原始数据转换为json数据
err := context.ShouldBindJSON(&jsondata)
if err != nil {
return
}
fmt.Println("json")
case "application/xml":
fmt.Println("xml")
}
fmt.Println(string(data))
}
main: router.POST("/raw", raw)
请求方式
当客户端(如浏览器)需要从服务器获取或发送数据时,它会向服务器发送一个请求。请求包含了一些信息,如请求方法(GET、POST等)、URL、请求头(包含一些元信息,如内容类型、认证信息等)和请求体(当使用POST或PUT等方法时,可以在请求体中发送数据)
RESTful是一种软件架构风格,它是Representational State Transfer(表现层状态转移)的缩写。RESTful架构主要用于客户端和服务器之间的交互,它基于HTTP协议,使用HTTP的请求方法来实现资源的增删改查。
-
GET:用于获取资源。GET请求应该只是读取数据,并且不会对数据产生任何影响。
-
POST:用于创建新的资源。POST请求通常会在服务器上创建新的资源,并且服务器会在响应中返回新资源的URI。
-
PUT:用于更新资源。PUT请求会替换目标资源的所有当前表示。(客户端提供完整数据)
-
DELETE:用于删除资源。DELETE请求会删除指定的资源。
-
PATCH:用于部分更新资源。与PUT不同,PATCH请求只更新资源的部分内容。(提供需要修改的资源数据)
在RESTful架构中,每个URL代表一种资源,客户端和服务器之间,传递这种资源的某种表现层。客户端通过四个HTTP动词,对服务器端资源进行操作,实现”表现层状态转移”。
import (
"fmt"
"github.com/gin-gonic/gin")
// 构造文章表
type Article struct {
Id int `json:"id"`
Title string `json:"title"`
}
// 封装response
type Response struct {
Code int `json:"code"`
Msg string `json:"msg"`
Data interface{} `json:"data"`
}
// restful四大请求方式
// GET:获取资源
func getlist(context *gin.Context) {
// 构造数据
articles := []Article{
{Id: 1, Title: "文章1"},
{Id: 2, Title: "文章2"},
{Id: 3, Title: "文章3"},
}
context.JSON(200, Response{
Code: 200,
Msg: "success",
Data: articles,
})
}
// GETDETAIL:获取资源详情
func getdetail(context *gin.Context) {
// 获取参数(param的id)
id := context.Param("id")
fmt.Println(id)
article := Article{
Id: 1,
Title: "文章1",
}
context.JSON(200, Response{
Code: 200,
Msg: "success",
Data: article,
})
}
// 剩下的需要用户传递参数
// POST:创建资源
func create(context *gin.Context) {
//context.JSON(200, gin.H{"method": "POST"})
// 就收前端传递的json数据
var article Article
err := context.ShouldBindJSON(&article)
if err != nil {
return
}
context.JSON(200, Response{
Code: 200,
Msg: "success",
Data: article,
})
}
// PUT:更新资源
func update(context *gin.Context) {
//context.JSON(200, gin.H{"method": "PUT"})
fmt.Println(context.Param("id"))
var article Article
err := context.ShouldBindJSON(&article)
if err != nil {
return
}
context.JSON(200, Response{
Code: 200,
Msg: "success",
Data: article,
})
}
// DELETE:删除资源
func delete(context *gin.Context) {
//context.JSON(200, gin.H{"method": "DELETE"})
fmt.Println(context.Param("id"))
context.JSON(200, Response{
Code: 200,
Msg: "del success",
Data: nil,
})
}
func main() {
router := gin.Default()
//注册路由
router.GET("/list", getlist)
router.GET("/list/:id", getdetail)
router.POST("/list", create)
router.PUT("/list/:id", update)
router.DELETE("/list/:id", delete)
//启动服务
err := router.Run(":8080")
if err != nil {
return
}
}
Ajax
Ajax(Asynchronous JavaScript and XML)是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。通过在后台与服务器进行少量数据交换,Ajax可以使网页实现异步更新。这意味着可以在网页上进行局部更新,而无需刷新整个页面。
展示如何在Go后端处理一个Ajax GET请求:
package main
import (
"github.com/gin-gonic/gin"
)
func handleAjax(context *gin.Context) {
// 获取Ajax请求的参数
param := context.Query("param")
// 返回JSON响应
context.JSON(200, gin.H{
"status": "success",
"param": param,
})
}
func main() {
router := gin.Default()
router.GET("/ajax", handleAjax)
router.Run(":8080")
}
定义处理函数handleAjax
,获取Ajax请求的参数,并返回一个JSON响应。然后,在主函数中创建路由,将/ajax
路径映射到handleAjax
函数。
在前端JavaScript中,使用fetch
、axios
或者jQuery.ajax
等方法来发送Ajax请求。例:
fetch('/ajax?param=value')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
向/ajax
路径发送了一个带有查询参数param=value
的GET请求,然后处理返回的JSON响应。
bind 绑定参数
Gin提供了一系列的Bind
函数,用于将请求的参数绑定到Go的结构体中。这些函数可以处理各种类型的请求和数据格式,包括JSON、XML、表单数据等。
常用的Bind
函数:
-
BindJSON(&struct)
: 此函数将请求的Body中的JSON数据绑定到结构体中。它首先检查Content-Type是否为application/json
,然后使用json.Unmarshal
将Body中的数据解析到结构体。 -
BindQuery(&struct)
: 此函数将请求的查询参数绑定到结构体中。它使用url.Values
解析查询参数,并将结果绑定到结构体。 -
Bind(&struct)
: 此函数根据请求的Content-Type自动选择合适的绑定函数。例如,如果Content-Type为application/json
,则使用BindJSON
。
这些函数都会返回一个错误,如果绑定过程中发生错误,检查并处理。
package main
import (
"github.com/gin-gonic/gin"
)
type Login struct {
User string `form:"user" json:"user" binding:"required"`
Password string `form:"password" json:"password" binding:"required"`
}
func main() {
router := gin.Default()
router.POST("/login", func(c *gin.Context) {
var login Login
if err := c.ShouldBindJSON(&login); err != nil {
c.JSON(400, gin.H{"error": err.Error()})
return
}
if login.User != "manu" || login.Password != "123" {
c.JSON(401, gin.H{"status": "unauthorized"})
return
}
c.JSON(200, gin.H{"status": "you are logged in"})
})
router.Run()
}
定义一个Login
结构体,用于接收登录请求的参数。然后在/login
路由的处理函数中,用c.ShouldBindJSON(&login)
将请求的JSON数据绑定到Login
结构体。如果绑定过程中发生错误,返回错误响应。如果绑定成功,检查用户名和密码,然后返回相应的响应。
笺評 (issue)