Gin 框架学习:将 request body 绑定到不同的结构体中

一般通过调用 c.Request.Body 方法绑定数据,但不能多次调用这个方法。

要想多次绑定,可以使用 c.ShouldBindBodyWith.

  • c.ShouldBindBodyWith 会在绑定之前将 body 存储到上下文中。 这会对性能造成轻微影响,如果调用一次就能完成绑定的话,那就不要用这个方法。
  • 只有某些格式需要此功能,如 JSONXMLMsgPackProtoBuf。 对于其他格式, 如 QueryFormFormPostFormMultipart 可以多次调用 c.ShouldBind() 而不会造成任任何性能损失 (详见 #1341)。
分类至 GO
0条评论

Gin 框架学习:记录访问日志

将访问日志写入到文件:

package main

import (
	"io"
	"os"

	"github.com/gin-gonic/gin"
)

func main() {
	// 禁用控制台颜色,将日志写入文件时不需要控制台颜色。
	gin.DisableConsoleColor()

	// 加入到文件
	f, _ := os.Create("gin.log")
	gin.DefaultWriter = io.MultiWriter(f)

	// 如果需要同时将日志写入文件和控制台,请使用以下代码。
	// gin.DefaultWriter = io.MultiWriter(f, os.Stdout)

	router := gin.Default()
	router.GET("/ping", func(c *gin.Context) {
		c.String(200, "pong")
	})

	router.Run(":8080")
}

注意:如果服务重启,日志文件会被覆盖。

分类至 GO
0条评论

Gin 框架学习:在中间件中使用 Goroutine

当在中间件或 handler 中启动新的 Goroutine 时,不能使用原始的上下文,必须使用只读副本。

package main

import (
	"log"
	"time"

	"github.com/gin-gonic/gin"
)

func main() {
	r := gin.Default()

	r.GET("/long_async", func(c *gin.Context) {
		// 创建在 goroutine 中使用的副本
		cCp := c.Copy()
		go func() {
			// 用 time.Sleep() 模拟一个长任务。
			time.Sleep(5 * time.Second)

			// 请注意您使用的是复制的上下文 "cCp",这一点很重要
			log.Println("Done! in path " + cCp.Request.URL.Path)
		}()
	})

	r.GET("/long_sync", func(c *gin.Context) {
		// 用 time.Sleep() 模拟一个长任务。
		time.Sleep(5 * time.Second)

		// 因为没有使用 goroutine,不需要拷贝上下文
		log.Println("Done! in path " + c.Request.URL.Path)
	})

	// 监听并在 0.0.0.0:8080 上启动服务
	r.Run(":8080")
}

 

分类至 GO
0条评论

Gin 框架学习:只绑定 url 查询字符串

url 参数除了通过 c.Query() 或 c.DefaultQuery() 获取值,还可以绑定到结构体。

c.ShouldBindQuery() 函数只绑定 url 查询参数而忽略 post 数据。

示例代码:

package main

import (
	"log"

	"github.com/gin-gonic/gin"
)

type Person struct {
	Name    string `form:"name"`
	Address string `form:"address"`
}

func main() {
	route := gin.Default()
	route.Any("/testing", startPage)
	route.Run(":8085")
}

func startPage(c *gin.Context) {
	var person Person
	if c.ShouldBindQuery(&person) == nil {
		log.Println("------ Only Bind By Query String ======")
		log.Println(person.Name)
		log.Println(person.Address)
	}
	c.String(200, "Success")
}

 

分类至 GO
0条评论

Gin 框架学习:使用 HTTP 方法

Gin 框架支持的 HTTP 方法有:GET、POST、PUT、DELETE、PATCH、HEAD、OPTIONS

func main() {
	// 禁用控制台颜色
	// gin.DisableConsoleColor()

	// 使用默认中间件(logger 和 recovery 中间件)创建 gin 路由
	router := gin.Default()

	router.GET("/someGet", getting)
	router.POST("/somePost", posting)
	router.PUT("/somePut", putting)
	router.DELETE("/someDelete", deleting)
	router.PATCH("/somePatch", patching)
	router.HEAD("/someHead", head)
	router.OPTIONS("/someOptions", options)

	// Any 表示此 url 接受任意 HTTP 方法
	router.Any("/any", any)

	// 默认在 8080 端口启动服务,除非定义了一个 PORT 的环境变量。
	router.Run()
	// router.Run(":3000") hardcode 端口号
}

 

分类至 GO
0条评论

小程序 wx.requestSubscribeMessage 调起订阅消息界面

微信小程序的订阅消息接口 wx.requestSubscribeMessage,只能是用户发生点击行为或者发起支付回调后,才可以调起订阅消息界面。

除去支付回调这种情况,你必须给页面某个元素绑定 tap 事件,把这个 API 放到 tap 事件里,当用户去点击这个元素时才能调起订阅消息界面,且不能通过 setTimeout 延迟执行。

有一种特殊情况,wx.showModal 模态窗口的 success 回调可以调起订阅消息界面,举例如下:

wx.showModal({
    showCancel: false,
    content: '操作成功',
    success: res => {
        wx.requestSubscribeMessage({
            tmplIds: [''],
            success: res => { }
        })
    }
})

 

分类至 小程序
0条评论

Git 配置多个 SSH-Key(来自码云)

背景

当有多个git账号时,比如:

a. 一个gitee,用于公司内部的工作开发;
b. 一个github,用于自己进行一些开发活动;

解决方法

  1. 生成一个公司用的SSH-Key
$ ssh-keygen -t rsa -C 'xxxxx@company.com' -f ~/.ssh/gitee_id_rsa
  1. 生成一个github用的SSH-Key
$ ssh-keygen -t rsa -C 'xxxxx@qq.com' -f ~/.ssh/github_id_rsa
  1. 在 ~/.ssh 目录下新建一个config文件,添加如下内容(其中Host和HostName填写git服务器的域名,IdentityFile指定私钥的路径)...
分类至 杂项
0条评论

Git 生成/添加 SSH 公钥(来自码云)

码云提供了基于SSH协议的Git服务,在使用SSH协议访问仓库仓库之前,需要先配置好账户/仓库的SSH公钥。

你可以按如下命令来生成 sshkey:

ssh-keygen -t rsa -C "xxxxx@xxxxx.com"  
# Generating public/private rsa key pair...

按照提示完成三次回车,即可生成 ssh key。通过查看 ~/.ssh/id_rsa.pub 文件内容,获取到你的 public key

cat ~/.ssh/id_rsa.pub
# ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC6eNtGpNGwstc....

...

分类至 杂项
0条评论

iOS 系统 Emoji 表情对应的 png 图片打包下载

最近有个需求,根据前台用户输入的内容在后台生成宣传图。

我的方法是,把内容渲染成一个 HTML 页面,然后使用 wkhtmltoimage 把网页转换成图片。遇到了一个问题:用户输入的内容带有 Emoji 表情符号,由于 Linux 服务器上没有对应的字体问题,生成图片的时候,Emoji 表情符号全变成了无法识别的框框。

当时我想,要是能把 iOS 系统的 Emoji 表情字体文件 Copy 过来用,那就完美了。在网上搜罗了很久,最终无功而返, iOS 系统的字体文件不能直接在其他系统上使用!

最后,我打算用最笨的方法,就是把 Emoji 表情符号替换成 PNG 图片来显示。即把原来的 Emoji 符号替换成 HTML 的 img 标签。

在 https://www.unicode.org/ 找到了所有 Emoji 表情对应的图片。两个页面,每个页面大概 25MB,打开很慢的,地址分别是...

分类至 杂项
0条评论

linux zip 打包时排除指定目录

zip 指令参数说明:

[root@VM_0_10_centos ~]# zip
Copyright (c) 1990-2008 Info-ZIP - Type 'zip "-L"' for software license.
Zip 3.0 (July 5th 2008). Usage:
zip [-options] [-b path] [-t mmddyyyy] [-n suffixes] [zipfile list] [-xi list]
  The default action is to add or replace zipfile entries from list, which
  can include the special name - to compress standard input.
  If zipfile and list are omitted, zip compresses stdin to stdout.
  -f   freshen: only changed files  -u   update: only changed or new files
  -d   delete entries in zipfile    -m   move into zipfile (delete OS files)
  -r   recurse into directories     -j   junk (don't record) directory names
  -0   store only                   -l   convert LF to CR LF (-ll CR LF to LF)
  -1   compress faster              -9   compress better
  -q   quiet operation              -v   verbose operation/print version info
  -c   add one-line comments        -z   add zipfile comment
  -@   read names from stdin        -o   make zipfile as old as latest entry
  -x   exclude the following names  -i   include only the following names
  -F   fix zipfile (-FF try harder) -D   do not add directory entries
  -A   adjust self-extracting exe   -J   junk zipfile prefix (unzipsfx)
  -T   test zipfile integrity       -X   eXclude eXtra file attributes
  -y   store symbolic links as the link instead of the referenced file
  -e   encrypt                      -n   don't compress these suffixes
  -h2  show more help

打包某个目录下的所有文件和子目录时,可以用 -r 递归参数,要排除某个目录或文件可以用 -x 参数。但是要注意,-x 参数如果是排除目录,要用双引号包裹,末尾要加 * 号。

打包时排除某个文件:

zip -r yangdx.zip yangdx/ -x yangdx/test.txt

打包时排除 cache、vendor 目录:

zip -r yangdx.zip yangdx/ -x "yangdx/cache/*" -x "yangdx/vendor/*"

 

分类至 Linux
0条评论