gin框架提高篇(四)

参数校验(一)

uuid包:https://github.com/satori/go.uuid
因为作者更改了参数限制,导致会出问题 → 问题解决

package mainimport ("fmt""github.com/gin-gonic/gin""github.com/go-playground/validator/v10"uuid "github.com/gofrs/uuid""net/http""unicode/utf8"
)type UserInfo struct {Id   string `validate:"uuid" json:"id"`           // UUID 类型Name string `validate:"checkName" json:"name"`    // 自定义校验Age  uint8  `validate:"min=0,max=130" json:"age"` // 大于0小于130
}var validate *validator.Validate// 校验初始化
func init() {validate = validator.New()                              // 初始化校验示例validate.RegisterValidation("checkName", checkNameFunc) // 自定义校验方法
}func checkNameFunc(fl validator.FieldLevel) bool {count := utf8.RuneCountInString(fl.Field().String()) // 获取 Name 的字符串表示,并计算 Unicode 字符的数量if count >= 2 && count <= 12 {return true}return false
}func main() {uuid.Must(uuid.NewV4()) // 由 uuid包 生成 uuidr := gin.Default()var user UserInfor.POST("/validate", func(context *gin.Context) {err := context.Bind(&user)if err != nil {context.JSON(http.StatusBadRequest, "请求参数错误")return}err = validate.Struct(user)if err != nil {for _, e := range err.(validator.ValidationErrors) {fmt.Println("错误的字段:", e.Field())fmt.Println("错误的值:", e.Value())fmt.Println("错误的tag:", e.Tag())}context.JSON(http.StatusBadRequest, "数据校验失败")return}context.JSON(http.StatusOK, "数据校验成功")})r.Run(":9090")
}

在这里插入图片描述

参数校验(二)

validator包:https://github.com/go-playground/validator

package mainimport ("fmt""github.com/gin-gonic/gin""github.com/go-playground/validator/v10""net/http"
)type ValUser struct {Name  string `validate:"required" json:"name"`Age   uint8  `validate:"gte=0,lte=130" json:"age"`Email string `validate:"required,email" json:"email"`// 切片数据类型Address []ValAddress `validate:"dive" json:"address"`
}type ValAddress struct {Province string `validate:"required" json:"province"`City     string `validate:"required" json:"city"`Phone    string `validate:"numeric,len=11" json:"phone"`
}var validate *validator.Validatefunc init() {validate = validator.New() // 初始化
}func main() {r := gin.Default()var user ValUserr.POST("/validate", func(context *gin.Context) {//testData(context)err := context.Bind(&user)if err != nil {context.JSON(http.StatusBadRequest, "参数错误,绑定失败")return}// 参数校验if validateUser(user) {context.JSON(http.StatusOK, "数据校验成功")return}context.JSON(http.StatusBadRequest, "校验失败")return})r.Run(":9090")
}//func testData(context *gin.Context) {
//	address := ValAddress{
//		Province: "浙江省",
//		City:     "杭州市",
//		Phone:    "13575121689",
//	}
//	user := ValUser{
//		Name:    "张三",
//		Age:     15,
//		Email:   "1993036922@qq.com",
//		Address: []ValAddress{address},
//	}
//	context.JSON(http.StatusOK, user)
//}func validateUser(u ValUser) bool {err := validate.Struct(u)if err != nil {for _, e := range err.(validator.ValidationErrors) {fmt.Println("错误的字段:", e.Field())fmt.Println("错误的值:", e.Value())fmt.Println("错误的tag:", e.Tag())}return false}return true
}

在这里插入图片描述

swagger

swagger地址:https://github.com/swaggo/gin-swagger

引入步骤

  • 下载swag及相关包
    • go get -u github.com/swaggo/swag/cmd/swag
    • go get -u github.com/swaggo/gin-swagger
    • go get -u github.com/swaggo/files
  • 实现 Api 代码
  • 编写注释:参考https://github.com/swaggo/swag/blob/master/README.md#declarative-comments-format
  • 在代码中使用 swagger 中间件
  • 引入docs:如我的引入为 _ “2-golang/docs”,_ 表示不为包赋名
  • 执行终端命令:swag init

如果出现 swag 不是命令,无法识别,则先执行: go install github.com/swaggo/swag/cmd/swag@latest

ps:文件名必须叫 main

package mainimport (_ "2-golang/docs""fmt""github.com/gin-gonic/gin"swaggerFiles "github.com/swaggo/files"ginSwagger "github.com/swaggo/gin-swagger""net/http"
)type User struct {UserName string `json:"user_name"`Password string `json:"password"`
}type Response struct {Code int    `json:"code"`Msg  string `json:"msg"`Data string `json:"data"`
}func main() {r := gin.Default()// 使用 swagger 中间件r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))r.GET("/login", login)r.POST("/register", register)r.Run(":9090")
}// @Tags 注册接口
// @Summary 注册
// @Description register
// @Accept json
// @Produce json
// @Param username formData string true "用户名"
// @Param password formData string true "密码"
// @Success 200 {string} json "{"code": 200, "data":"{"name":"username","password":"password"}","msg":"OK"}"
// @Router /register [post]
func register(context *gin.Context) {var user User// get 使用的是 query,post 使用的是 formData,而 Bind 只能绑定 query// err := context.Bind(&user)err := context.BindQuery(&user)if err != nil {context.JSON(http.StatusBadRequest, "数据错误")return}res := Response{Code: http.StatusOK,Msg:  "注册成功",Data: "OK",}context.JSON(http.StatusOK, res)
}// @Tags 登录接口
// @Summary 登录
// @Description login
// @Accept json
// @Produce json
// @Param username query string true "用户名"
// @Param password query string false "密码"
// @Success 200 {string} json "{"code": 200, "data":"{"name":"username","password":"password"}","msg":"OK"}"
// @Router /login [get]
func login(context *gin.Context) {userName := context.Query("name")pwd := context.Query("pwd")fmt.Println(userName, pwd)res := Response{}res.Code = http.StatusOKres.Msg = "登陆成功"res.Data = "OK"context.JSON(http.StatusOK, res)
}

在这里插入图片描述

gin框架cookie

package mainimport ("encoding/hex""fmt""github.com/gin-gonic/gin""net/http"
)var cookieName string
var cookieValue stringfunc main() {r := gin.Default()r.Use(cookieAuth())r.GET("/cookie", func(context *gin.Context) {name := context.Query("name")if len(name) <= 0 {context.JSON(http.StatusOK, "数据错误")return}cookieName = "cookie_" + namecookieValue = hex.EncodeToString([]byte(cookieName + "value"))val, _ := context.Cookie(cookieName)if val == "" {context.String(http.StatusOK, "Cookie已经下发,下次登录有效", cookieName)return}context.String(http.StatusOK, "验证成功,cookie值为:%s", val)})r.Run(":9090")
}func cookieAuth() gin.HandlerFunc {return func(context *gin.Context) {val, _ := context.Cookie(cookieName)if val == "" {context.SetCookie(cookieName, cookieValue, 3600, "/", "localhost", true, true)fmt.Println("cookie已经保存完成!")}}
}

在这里插入图片描述

gin框架session

package mainimport ("net/http""github.com/gin-contrib/sessions""github.com/gin-contrib/sessions/cookie""github.com/gin-gonic/gin"
)func main() {r := gin.Default()// 加入 session 中间件store := cookie.NewStore([]byte("session_secret")) // 创建基于cookie的session存储r.Use(sessions.Sessions("mySession", store))       // 使用session中间件,并指定session名称和存储方式r.GET("/session", func(context *gin.Context) {name := context.Query("name")if len(name) <= 0 {context.JSON(http.StatusOK, "数据错误")return}sessionName := "session_" + name        // 构造session名称sessionValue := "session_value_" + name // 构造session值session := sessions.Default(context) // 获取默认的session实例sessionData := session.Get(sessionName)if sessionData != sessionValue { // 如果session中不存在对应值,则为首次访问session.Set(sessionName, sessionValue) // 设置 sessionsession.Save()                         // 保存 sessioncontext.JSON(http.StatusOK, "首次访问,session已保存:"+sessionValue)return}context.JSON(http.StatusOK, "访问成功,您的session是:"+sessionData.(string))})r.Run(":9090") // 启动HTTP服务器,监听9090端口
}

gin框架Https

  • 申请证书并下载证书:https://keymanager.org/
    在这里插入图片描述

在这里插入图片描述

package mainimport ("github.com/gin-gonic/gin""github.com/unrolled/secure""net/http"
)// HttpRes 结构体用于定义HTTP响应格式
type HttpRes struct {Code   int    `json:"code"`   // 响应状态码Result string `json:"result"` // 响应结果消息
}func main() {r := gin.Default() // 创建默认的gin路由引擎// 使用HTTPS处理程序中间件r.Use(httpsHandler())// 定义GET路由"/https_test"r.GET("/https_test", func(context *gin.Context) {// 返回JSON格式的成功消息context.JSON(http.StatusOK, HttpRes{Code:   http.StatusOK,Result: "测试成功",})})path := "D:/2-golang/CA/"                       // 证书路径r.RunTLS(":9090", path+"ca.crt", path+"ca.key") // 使用TLS在9090端口运行服务器
}// httpsHandler 返回一个处理HTTPS请求的中间件函数
func httpsHandler() gin.HandlerFunc {return func(context *gin.Context) {// 创建secure中间件实例secureMiddleware := secure.New(secure.Options{SSLRedirect:          true, // 强制SSL重定向STSSeconds:           1536000,STSIncludeSubdomains: true,STSPreload:           true,FrameDeny:            true,ContentTypeNosniff:   true,BrowserXssFilter:     true,})// 处理HTTPS请求err := secureMiddleware.Process(context.Writer, context.Request)if err != nil {// 如果出现错误,返回数据不安全的响应context.AbortWithStatusJSON(http.StatusBadRequest, "数据不安全")return}if status := context.Writer.Status(); status > 300 && status < 399 {// 如果响应状态码是重定向类型,则终止请求context.Abort()return}context.Next() // 继续处理下一个中间件或路由处理函数}
}

在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/658.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

盲人盲杖:科技革新,助力视障人士独立出行

在我们的社会中&#xff0c;盲人朋友们以其坚韧的精神风貌&#xff0c;生动诠释着生活的多样与可能。然而&#xff0c;当我们聚焦于他们的日常出行&#xff0c;那些普通人视为寻常的街道、路口&#xff0c;却成为他们必须面对的严峻挑战。如何切实提升盲人盲杖的功能&#xff0…

【Linux进阶之路】高级IO

一、 铺垫 I&#xff0c;即input为输入&#xff1b;O&#xff0c;即output为输出&#xff0c;IO&#xff0c;即input output为输入输出。IO一般是基于网卡&#xff0c;磁盘&#xff0c;光盘&#xff0c;U盘&#xff0c;磁盘&#xff0c;磁带等毫秒级别的外存&#xff0c;相较…

Python实现贪吃蛇

提供学习或者毕业设计使用,功能基本都有,不能和市场上正式游戏相提比论,请理性对待!通过购买专栏或者CSDN问答提问,采纳后,私信博主。提供源码! 说明:需要的话联系博主!谢谢。 代码: import pygame import random import tkinter as tk from tkinter import mess…

BetterZip 5 for Mac:轻松解压缩的得力助手

BetterZip 5 for Mac是一款专为苹果电脑用户设计的压缩与解压软件&#xff0c;以其强大的功能和便捷的操作赢得了广大用户的喜爱。 BetterZip 5 for Mac v5.3.4中文版下载 这款软件支持多种主流的压缩格式&#xff0c;如ZIP、RAR、7-Zip等&#xff0c;满足了用户多样化的需求。…

WordPress 主题选择与自定义配置

最近我在使用wordpress网站进行建站。 我是使用的hostease的主机产品进行wordpress建站&#xff0c;在选择wordpress主题时颇为头疼。后来咨询了hostease的客服人员&#xff0c;他们家的技术人员提供了诸多帮助。在WordPress网站建设时&#xff0c;主题选择对于建立各类网站至关…

【MIT6.824】lab2C-persistence, lab2D-log compaction 实现笔记

引言 lab2C的实验要求如下 Complete the functions persist() and readPersist() in raft.go by adding code to save and restore persistent state. You will need to encode (or “serialize”) the state as an array of bytes in order to pass it to the Persister. Us…

记录——FPGA的学习路线

文章目录 一、前言二、编程语言2.1 书籍2.2 刷题网站2.3 仿真工具 三、基础知识3.1 专业基础课3.2 fpga相关专业知识 四、开发工具五、动手实验 一、前言 也不是心血来潮想学习fpga了&#xff0c;而是祥哥还有我一个国科大的同学都在往fpga这个方向走 并且看过我之前文章的同…

合并有序表 (顺序存储 和 链式存储 方式实现)

代码详细解析: 合并有序表文章浏览阅读1.4k次&#xff0c;点赞6次&#xff0c;收藏7次。●假设有两个有序表 LA和LB , 将他们合并成一个有序表LC●要求不破坏原有的表 LA和 LB构思:把这两个表, 合成一个有序表 , 不是简简单单吗?就算是把他们先遍历不按顺序插入到表 C里面 , …

万物皆可计算|下一个风口:近内存计算-2

虽然PIM可以有缓解内存墙的问题&#xff0c;但是PIM设计面临着一系列技术和工程上的挑战&#xff0c;这些挑战直接影响着PIM技术的实用化和广泛应用&#xff1a; 地址翻译与操作映射&#xff1a; 在传统计算机体系结构中&#xff0c;地址空间由操作系统管理和调度&#xff0c;通…

Hotcoin 热门资产上新速报:以太坊互操作性基础设施Omni Network(OMNI)

Hotcoin持续为全球600万用户发掘优质潜力资产&#xff0c;热门币种交易上热币。一文快速了解今日上新资产:Omni Network&#xff08;OMNI&#xff09; 推荐指数 8.4 交易对 OMNI/USDT 交易时间 4月17日 GMT8 20&#xff1a;30 资产赛道 Layer1 项目简介 Omni 是以太坊…

【星瑞格】SinoDB国产数据库安装初体验及学习指南

今天和大家一起来看看一款来自福建的国产数据库——SinoDB。本人很早就听说过这款数据库&#xff0c;而且星瑞格公司就在同一栋办公楼。虽然以前就已经对这颗国产数据库有一定的了解&#xff0c;并没有真正的去使用一把。随着数据库国产化改造工作的推进&#xff0c;身边的客户…

vue+springboot实现聊天功能

前言 在我的项目中&#xff0c;突然有种想法&#xff0c;想实现聊天功能&#xff0c;历经一段时间终于做出来了&#xff1b;那么接下来会讲解如何实现&#xff0c;这篇文章只会实现最基础的逻辑&#xff0c;实时获取对方聊天记录&#xff0c;话不多说&#xff0c;我们就开始吧…

吹爆,一款实用的个人IT工具箱

作为一名开发人员&#xff0c;我们在日常工作和学习中常常需要使用一系列小工具&#xff0c;如JSON格式化、JSON转表格、当前时间戳、XML格式化、SQL格式化、密码生成以及UUID生成等。通常情况下&#xff0c;我们会在网上搜索各种在线工具来满足这些需求。 然而&#xff0c;这…

【简单介绍下单片机】

&#x1f308;个人主页: 程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…

大学生简历大赛演讲稿(6篇)

大学生简历大赛演讲稿&#xff08;6篇&#xff09; 以下是六篇大学生简历大赛演讲稿的范文&#xff0c;供您参考&#xff1a; 范文一&#xff1a;展现真我&#xff0c;点亮未来 尊敬的评委、亲爱的同学们&#xff1a; 大家好&#xff01; 今天&#xff0c;我站在这里&#xf…

【C++】:C++关键字,命名空间,输入输出,缺省参数

目录 一&#xff0c;C关键字(C98)二&#xff0c;命名空间2.1 命名冲突2.2 关键字namespace2.2.1 命名空间中可以定义变量/函数/类型2.2.2 命名空间可以嵌套2.2.3 同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中。 2.3 命名空间的使用2.3.1 指定…

剑指offer之牛客与力扣——前者分类题单中的题目在后者的链接

搜索 [4.12完成] JZ1 LCR 172. 统计目标成绩的出现次数 JZ3 153. 寻找旋转排序数组中的最小值 JZ4 LCR 014. 字符串的排列 JZ5 LCR 163. 找到第 k 位数字 400 动态规划 [4.15完成] JZ2 LCR 161. 连续天数的最高销售额 53 JZ3 LCR 127. 跳跃训练 70 JZ4 LCR 126. 斐波那契…

gemini国内怎么用

gemini国内怎么用 Google Gemini 作为一个尚处于研发阶段的大型语言模型&#xff0c;其具体功能和性能尚未公开&#xff0c;因此无法对其好用程度做出明确评价。 然而&#xff0c;基于 Google 在人工智能领域的领先地位和技术实力&#xff0c;我们可以对其潜力进行一些推测&a…

大型网站系统架构演化实例_4.数据库读写分离

1.数据库读写分离 网站在使用缓存后&#xff0c;使对大部分数据读操作访问都可以不通过数据库就能完成&#xff0c;但是仍有一部分操作&#xff08;缓存访问不命中、缓存过期&#xff09;和全部的写操作都需要访问数据库&#xff0c;在网站的用户达到一定规模后&#x…

通过实例学C#之ArrayList

介绍 ArrayList对象可以容纳若干个具有相同类型的对象&#xff0c;那有人说&#xff0c;这和数组有什么区别呢。其区别大概可以分为以下几点&#xff1a; 1.数组效率较高&#xff0c;但其容量固定&#xff0c;而且没办法动态改变。 2.ArrayList容量可以动态增长&#xff0c;但…