zoukankan      html  css  js  c++  java
  • go语言web开发系列之三:gin用go-playground/validator做参数的校验

    一,演示项目的相关信息

    1,项目地址:

    https://github.com/liuhongdi/digv03

    2,功能说明:使用校验器(validator)实现对参数的校验

    3,项目结构:如图:

    说明:刘宏缔的go森林是一个专注golang的博客,
              地址:https://blog.csdn.net/weixin_43881017

    说明:作者:刘宏缔 邮箱: 371125307@qq.com

    二,sql说明

    1.  
      CREATE TABLE `article` (
    2.  
      `articleId` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
    3.  
      `type` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '类型',
    4.  
      `subject` varchar(500) NOT NULL DEFAULT '' COMMENT '标题',
    5.  
      `addTime` datetime NOT NULL DEFAULT '2020-11-19 00:00:00' COMMENT '添加时间',
    6.  
      `isHot` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '是否热榜,0:非热,1,热',
    7.  
      `url` varchar(500) NOT NULL DEFAULT '' COMMENT '链接地址',
    8.  
      `domain` varchar(100) NOT NULL DEFAULT '' COMMENT '域',
    9.  
      `userId` bigint unsigned NOT NULL DEFAULT '0' COMMENT '推荐用户',
    10.  
      `approvalStaffId` int unsigned NOT NULL DEFAULT '0' COMMENT '批准员工',
    11.  
      `digSum` int unsigned NOT NULL DEFAULT '0' COMMENT '被顶的次数',
    12.  
      `commentSum` int unsigned NOT NULL DEFAULT '0' COMMENT '被评论的次数',
    13.  
      `isPublish` tinyint NOT NULL DEFAULT '0' COMMENT '0,未发布,1,已发布',
    14.  
      PRIMARY KEY (`articleId`),
    15.  
      KEY `isPublish` (`isPublish`)
    16.  
      ) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='文章表'

    插入6条演示数据:

    1.  
      INSERT INTO `article` (`articleId`, `type`, `subject`, `addTime`, `isHot`, `url`, `domain`, `userId`, `approvalStaffId`, `digSum`, `commentSum`, `isPublish`) VALUES
    2.  
      (1, 0, '【最近,南非发现一座大油田】石油和天然气两种重要资源是南非储量的最短板,“贫油”的帽子也一直扣在南非的头上摘不下来。可就在最近,在南非海域进行油气勘探已久的道达尔透露了其新的勘探成果:在距离南非南部海岸约175公里的奥特尼夸盆地的11B/12B地区,再次发现了重要的凝析气,可能蕴藏着大量天然气及原油。', '2020-11-19 00:00:00', 1, 'https://mp.weixin.qq.com/s/1btbmouH-2KuIHUMoucq2w', '', 1, 1, 0, 0, 1),
    3.  
      (2, 1, '让喵喵来开启周五的早晨吧!', '2020-11-19 00:00:00', 0, 'https://m.weibo.cn/status/4573112073720433?', 'm.weibo.cn', 0, 0, 0, 0, 1),
    4.  
      (3, 0, '汤姆·赫兰德、黛茜·雷德利、麦斯·米科尔森、尼克·乔纳斯主演的《混沌漫步》公开预告。影片由《明日边缘》导演道格·里曼执导,暂时定档明年1月22日上映。', '2020-11-19 00:00:00', 1, 'http://news.mtime.com/2020/11/19/1604795.html', 'news.mtime.com', 0, 0, 0, 0, 1),
    5.  
      (4, 1, '扫地机器人这个东西确实方便,大多数时候把房间扫的比较干净,但还有很多边边角角清扫不上,希望厂家能够在app上显示出机器人的路线图,明确告知哪些路段没有照顾到,要不然就再开发一个项目经理机器人,跟在扫地机器人屁股后面监督。//@大窑儿:可以弄个步数排行榜,让机器人们互相点赞,揣摩,攀比,内卷,无意义竞争。', '2020-11-19 00:00:00', 0, '', '', 0, 0, 0, 0, 1),
    6.  
      (5, 0, '【世卫组织建议医生不要使用瑞德西韦治疗新冠】世卫组织指导小组表示,证据显示,瑞德西韦对提高新冠肺炎患者的存活率没有显著影响。这项建议发表在上周五的《英国医学杂志》中。', '2020-11-19 00:00:00', 0, 'https://www.thepaper.cn/newsDetail_forward_10067542', 'thepaper.cn', 0, 0, 0, 0, 1),
    7.  
      (6, 0, '11月19日0—24时,31个省(自治区、直辖市)和新疆生产建设兵团报告新增确诊病例17例,均为境外输入病例(福建6例,上海4例,陕西3例,广东2例,北京1例,四川1例);无新增死亡病例;新增疑似病例1例,为本土病例(在天津)。', '2020-11-19 00:00:00', 0, 'http://m.news.cctv.com/2020/11/20/ARTIIR9o72TuDF80s6hY2IvD201120.shtml', 'm.news.cctv.com', 0, 0, 0, 0, 1);

    三,go代码说明

    1,pkg/validCheck/convert.go

    1.  
      package validCheck
    2.  
       
    3.  
      import (
    4.  
      "strconv"
    5.  
      )
    6.  
       
    7.  
      type StrTo string
    8.  
       
    9.  
      func (s StrTo) String() string {
    10.  
      return string(s)
    11.  
      }
    12.  
       
    13.  
      func (s StrTo) Int() (int, error) {
    14.  
      v, err := strconv.Atoi(s.String())
    15.  
      return v, err
    16.  
      }
    17.  
       
    18.  
      func (s StrTo) MustInt() int {
    19.  
      v, _ := s.Int()
    20.  
      return v
    21.  
      }
    22.  
       
    23.  
      func (s StrTo) UInt32() (uint32, error) {
    24.  
      v, err := strconv.Atoi(s.String())
    25.  
      return uint32(v), err
    26.  
      }
    27.  
       
    28.  
      func (s StrTo) UInt64() (uint64, error) {
    29.  
      v, err := strconv.Atoi(s.String())
    30.  
      return uint64(v), err
    31.  
      }
    32.  
       
    33.  
      func (s StrTo) MustUInt32() uint32 {
    34.  
      curInt32, _ := strconv.Atoi(s.String())
    35.  
      if (curInt32 < 0) {
    36.  
      return 0;
    37.  
      }
    38.  
      v, _ := s.UInt32()
    39.  
      return v
    40.  
      }
    41.  
       
    42.  
      func (s StrTo) MustUInt64() uint64 {
    43.  
      //fmt.Println(s)
    44.  
      curInt64, _ := strconv.ParseInt(s.String(), 10, 64);
    45.  
      if (curInt64 < 0) {
    46.  
      return 0;
    47.  
      }
    48.  
      v, _ := s.UInt64()
    49.  
      //fmt.Println(v)
    50.  
      return v
    51.  
      }

    2,pkg/validCheck/requestValid.go

    1.  
      package validCheck
    2.  
       
    3.  
      import (
    4.  
      "github.com/gin-gonic/gin"
    5.  
      ut "github.com/go-playground/universal-translator"
    6.  
      val "github.com/go-playground/validator/v10"
    7.  
      "strings"
    8.  
      )
    9.  
       
    10.  
      type ValidError struct {
    11.  
      Key string
    12.  
      Message string
    13.  
      }
    14.  
       
    15.  
      type ValidErrors []*ValidError
    16.  
       
    17.  
      func (v *ValidError) Error() string {
    18.  
      return v.Message
    19.  
      }
    20.  
       
    21.  
      func (v ValidErrors) Error() string {
    22.  
      return strings.Join(v.Errors(), ",")
    23.  
      }
    24.  
       
    25.  
      func (v ValidErrors) Errors() []string {
    26.  
      var errs []string
    27.  
      for _, err := range v {
    28.  
      errs = append(errs, err.Error())
    29.  
      }
    30.  
       
    31.  
      return errs
    32.  
      }
    33.  
      //判断变量是否符合要求
    34.  
      func BindAndValid(c *gin.Context, v interface{}) (bool, ValidErrors) {
    35.  
      var errs ValidErrors
    36.  
      err := c.ShouldBind(v)
    37.  
      if err != nil {
    38.  
      v := c.Value("trans")
    39.  
      trans, _ := v.(ut.Translator)
    40.  
      verrs, ok := err.(val.ValidationErrors)
    41.  
      if !ok {
    42.  
      errs = append(errs, &ValidError{
    43.  
      Key: "field",
    44.  
      Message: err.Error(),
    45.  
      })
    46.  
      return false, errs
    47.  
      }
    48.  
      for key, value := range verrs.Translate(trans) {
    49.  
      errs = append(errs, &ValidError{
    50.  
      Key: key,
    51.  
      Message: value,
    52.  
      })
    53.  
      }
    54.  
       
    55.  
      return false, errs
    56.  
      }
    57.  
      return true, nil
    58.  
      }

    3,request/article.go

    1.  
      package request
    2.  
       
    3.  
      type ArticleRequest struct {
    4.  
      ID uint64 `form:"id" binding:"required,gte=1"`
    5.  
      //State uint8 `form:"state,default=1" binding:"oneof=0 1"`
    6.  
      }
    7.  
       
    8.  
      type ArticleListRequest struct {
    9.  
      Page int `form:"page" binding:"gte=1"`
    10.  
      //State uint8 `form:"state,default=1" binding:"oneof=0 1"`
    11.  
      }

    说明:验证的规则写在这里

    4,controller/articleController.go

    1.  
      package controller
    2.  
       
    3.  
      import (
    4.  
      "fmt"
    5.  
      "github.com/gin-gonic/gin"
    6.  
      "github.com/liuhongdi/digv03/global"
    7.  
      "github.com/liuhongdi/digv03/pkg/page"
    8.  
      "github.com/liuhongdi/digv03/pkg/validCheck"
    9.  
      "github.com/liuhongdi/digv03/request"
    10.  
      "github.com/liuhongdi/digv03/service"
    11.  
      )
    12.  
       
    13.  
      type ArticleController struct{}
    14.  
       
    15.  
      func NewArticleController() ArticleController {
    16.  
      return ArticleController{}
    17.  
      }
    18.  
      //得到一篇文章的详情
    19.  
      func (a *ArticleController) GetOne(c *gin.Context) {
    20.  
      result := global.NewResult(c)
    21.  
      param := request.ArticleRequest{ID: validCheck.StrTo(c.Param("id")).MustUInt64()}
    22.  
      valid, errs := validCheck.BindAndValid(c, &param)
    23.  
      if !valid {
    24.  
      result.Error(400,errs.Error())
    25.  
      return
    26.  
      }
    27.  
       
    28.  
      articleOne,err := service.GetOneArticle(param.ID);
    29.  
      if err != nil {
    30.  
      result.Error(404,"数据查询错误")
    31.  
      } else {
    32.  
      result.Success(&articleOne);
    33.  
      }
    34.  
      return
    35.  
      }
    36.  
       
    37.  
      //得到多篇文章,按分页返回
    38.  
      func (a *ArticleController) GetList(c *gin.Context) {
    39.  
      result := global.NewResult(c)
    40.  
      pageInt := 0
    41.  
      //is exist?
    42.  
      curPage := c.Query("page")
    43.  
      //if curPage not exist
    44.  
      if (len(curPage) == 0) {
    45.  
      pageInt = 1
    46.  
      } else {
    47.  
      param := request.ArticleListRequest{Page: validCheck.StrTo(c.Param("page")).MustInt()}
    48.  
      valid, errs := validCheck.BindAndValid(c, &param)
    49.  
      if !valid {
    50.  
      result.Error(400,errs.Error())
    51.  
      return
    52.  
      }
    53.  
      pageInt = param.Page
    54.  
      }
    55.  
       
    56.  
      pageSize := 2;
    57.  
      pageOffset := (pageInt-1) * pageSize
    58.  
       
    59.  
      articles,err := service.GetArticleList(pageOffset,pageSize)
    60.  
      if err != nil {
    61.  
      result.Error(404,"数据查询错误");
    62.  
      fmt.Println(err.Error())
    63.  
      } else {
    64.  
      //sum,_ := dao.SelectcountAll()
    65.  
      sum,_ := service.GetArticleSum()
    66.  
      pageInfo,_ := page.GetPageInfo(pageInt,pageSize,sum)
    67.  
      result.Success(gin.H{"list":&articles,"pageinfo":pageInfo});
    68.  
      }
    69.  
      return
    70.  
      }

    四,测试

    1,正常访问:

    http://127.0.0.1:8080/article/getone/1

    返回:

    2,输入非法数据:

    http://127.0.0.1:8080/article/getone/a

    返回:

    五,查看库的版本

    1.  
      module github.com/liuhongdi/digv03
    2.  
       
    3.  
      go 1.15
    4.  
       
    5.  
      require (
    6.  
      github.com/gin-gonic/gin v1.6.3
    7.  
      github.com/go-playground/universal-translator v0.17.0
    8.  
      github.com/go-playground/validator/v10 v10.2.0
    9.  
      github.com/jinzhu/gorm v1.9.16
    10.  
      )
  • 相关阅读:
    Nop中的Cache浅析
    使用DapperExtensions实现简单仓储
    使用nodejs爬取拉勾苏州和上海的.NET职位信息
    使用Microsoft Fakes进行单元测试(2)
    使用Microsoft Fakes进行单元测试(1)
    小程序之滚动到页面底部
    小程序之动态修改页面标题
    小程序之面试题
    小程序之公共组件的开发
    小程序之web-view打开外部链接
  • 原文地址:https://www.cnblogs.com/ExMan/p/14312168.html
Copyright © 2011-2022 走看看