美文网首页
Goframe框架细节

Goframe框架细节

作者: 小陈工 | 来源:发表于2022-07-11 11:01 被阅读0次

    一、OmitEmpty空值过滤

    空值会影响于写入/更新操作方法,如Insert, Replace, Update, Save操作。

    当 map/struct 中存在空值如 nil,"",0 时,默认情况下,gdb将会将其当做正常的输入参数,因此这些参数也会被更新到数据表。

    针对空值情况,我们可以通过OmitEmpty方法来过滤掉这些空值。

    示例:db.Table("user").OmitEmpty().Data(user).Insert()

    二、数据返回-模板解析

    Response支持模板文件/内容解析输出,或者模板文件/内容解析返回。与直接使用模板对象解析模板功能不同的是,Response的解析支持一些请求相关的内置变量。模板解析包含以下方法:

    WriteTpl*方法用于模板输出,解析并输出模板文件,也可以直接解析并输出给定的模板内容。

    ParseTpl*方法用于模板解析,解析模板文件或者模板内容,返回解析后的内容。

    解析模板时组件底层会自动通过Request对象获取当前链路的Context上下文变量并传递给模板引擎,因此开发者不用显示给模板引擎传递Context上下文变量。

    内置变量:

                1、Config:访问默认的配置管理(config.toml)对象配置项。

                                    使用方式:{{.Config.配置项}}

                2、Cookie:访问当前请求的Cookie对象参数值。

                                    使用方式:{{.Cookie.键名}}

                3、Session:访问当前请求的Session对象参数值。

                                     使用方式:{{.Session.键名}}

                4、Query:访问当前Query String中的请求参数值。

                                    使用方式:{{.Query.键名}}

                5、Form:访问当前表单请求参数值。

                                    使用方式:{{.Form.键名}}

                6、Request:访问当前请求参数值(不区分参数提交方式)。

                                    使用方式:{{.Request.键名}}

    三、请求输入-Context

    请求流程往往会在上下文中共享一些自定义设置的变量,例如在请求开始之前通过中间件设置一些变量,随后在路由服务方法中可以获取该变量并相应对一些处理。这种需求非常常见。在GoFrame框架中,我们推荐使用Context上下文对象来处理流程共享的上下文变量,甚至将该对象进一步传递到依赖的各个模块方法中。该Context对象类型实现了标准库的context.Context接口,该接口往往会作为模块间调用方法的第一个参数,该接口参数也是Golang官方推荐的在模块间传递上下文变量的推荐方式。

    方法列表:

    func(r*Request)GetCtx()context.Context

    func(r*Request)SetCtx(ctx context.Context)

    func(r*Request)GetCtxVar(keyinterface{},def...interface{})*gvar.Var

    func(r*Request)SetCtxVar(keyinterface{},valueinterface{})

    简要说明:

    GetCtx方法用于获取当前的context.Context对象,作用同Context方法。

    SetCtx方法用于设置自定义的context.Context上下文对象。

    GetCtxVar方法用于获取上下文变量,并可给定当该变量不存在时的默认值。

    SetCtxVar方法用于设置上下文变量。

    可以通过SetCtxVar和GetCtxVar来设置和获取自定义的变量,该变量生命周期仅限于当前请求流程。

    四、HTTPClient-文件上传

    在服务端通过Request对象获取上传文件:

    funcUpload(r*ghttp.Request){

    files:=r.GetUploadFiles("upload-file")

    names,err:=files.Save("/tmp/")

    iferr!=nil{

    r.Response.WriteExit(err)

    }

    r.Response.WriteExit("upload successfully: ",names)}

    关键代码说明

    我们在服务端可以通过r.GetUploadFiles方法获得上传的所有文件对象,也可以通过r.GetUploadFile获取单个上传的文件对象。

    在r.GetUploadFiles("upload-file")中的参数"upload-file"为本示例中客户端上传时的表单文件域名称,开发者可以根据前后端约定在客户端中定义,以方便服务端接收表单文件域参数。

    通过files.Save可以将上传的多个文件方便地保存到指定的目录下,并返回保存成功的文件名。如果是批量保存,只要任意一个文件保存失败,都将会立即返回错误。此外,Save方法的第二个参数支持随机自动命名上传文件。

    通过group.POST("/", Upload)注册的路由仅支持POST方式访问。

    文件上传参数格式使用了 参数名=@file:文件路径 ,HTTP客户端将会自动解析文件路径对应的文件内容并读取提交给服务端。原本复杂的文件上传操作被gf进行了封装处理,用户只需要使用 @file:+文件路径 来构成参数值即可。其中,文件路径请使用本地文件绝对路径。

    多个文件上传提交参数格式为参数名=@file:xxx&参数名=@file:xxx...,也可以使用参数名[]=@file:xxx&参数名[]=@file:xxx...的形式。

    五、Session

    任何时候都可以通过ghttp.Request获取Session对象,因为Cookie和Session都是和请求会话相关,因此都属于Request的成员对象,并对外公开。GoFrame框架的Session默认过期时间是24小时。

    SessionId默认通过Cookie来传递,并且也支持客户端通过Header传递SessionId,SessionId的识别名称可以通过ghttp.Server的SetSessionIdName进行修改。Session的操作是支持并发安全的,这也是框架在对Session的设计上不采用直接以map的形式操作数据的原因。在HTTP请求流程中,我们可以通过ghttp.Request对象来获取Session对象,并执行相应的数据操作。

    gsession模块

    Session的管理功能由独立的gsession模块实现,并已完美整合到了ghttp.Server中。由于该模块是解耦独立的,因此可以应用到更多不同的场景中,例如:TCP通信、gRPC接口服务等等。在gsession模块中有比较重要的三个对象/接口:

    gsession.Manager:管理Session对象、Storage持久化存储对象、以及过期时间控制。

    gsession.Session:单个Session会话管理对象,用于Session参数的增删查改等数据管理操作。

    gsession.Storage:这是一个接口定义,用于Session对象的持久化存储、数据写入/读取、存活更新等操作,开发者可基于该接口实现自定义的持久化存储特性。

    Session的初始化

    以常见的HTTP请求为例。ghttp.Request中的Session对象采用了"懒初始化(LazyInitialization)"设计方式,默认在Request中有一个Session属性对象,但是并未初始化(一个空对象),只有在使用Session属性对象的方法时才会真正执行初始化。这样的设计既保障了未使用Session特性的请求执行性能,也保证了组件使用的易用性。

    Session的销毁/注销

    用户Session不再使用,例如用户注销登录状态,需要从存储中硬删除,那么可以调用RemoveAll方法。

    在默认情况下,ghttp.Server的Session存储使用了内存+文件的方式,使用StorageFile对象实现。具体原理为:

    Session的数据操作完全基于内存;

    使用gcache进程缓存模块控制数据过期;

    使用文件存储持久化存储管理Session数据;

    当且仅有当Session被标记为dirty时(数据有更新)才会执行Session序列化并执行文件持久化存储;

    当且仅当内存中的Session不存在时,才会从文件存储中反序列化恢复Session数据到内存中,降低IO调用;

    序列化/反序列化使用的是标准库的json.Marshal/UnMarshal方法;

    六、日志管理

    使用配置文件的方式来管理服务配置以及日志配置。 一个参考的日志配置内容示例(以yaml格式为例):

    logger:

    path:"/var/log/"# 日志文件路径。默认为空,表示关闭,仅输出到终端

    file:"{Y-m-d}.log"# 日志文件格式。默认为"{Y-m-d}.log"

    prefix:""# 日志内容输出前缀。默认为空

    level:"all"# 日志输出级别

    ctxKeys:[]# 自定义Context上下文变量名称,自动打印Context的变量到日志中。默认为空

    header:true# 是否打印日志的头信息。默认true

    stdout:true# 日志是否同时输出到终端。默认true

    rotateSize:0# 按照日志文件大小对文件进行滚动切分。默认为0,表示关闭滚动切分特性

    rotateExpire:0# 按照日志文件时间间隔对文件滚动切分。默认为0,表示关闭滚动切分特性

    rotateBackupLimit:0# 按照切分的文件数量清理切分文件,当滚动切分特性开启时有效。默认为0,表示不备份,切分则删除

    rotateBackupExpire:0# 按照切分的文件有效期清理切分文件,当滚动切分特性开启时有效。默认为0,表示不备份,切分则删除

    rotateBackupCompress:0# 滚动切分文件的压缩比(0-9)。默认为0,表示不压缩

    rotateCheckInterval:"1h"# 滚动切分的时间检测间隔,一般不需要设置。默认为1小时

    stdoutColorDisabled:false# 关闭终端的颜色打印。默认开启

    writerColorEnable:false# 日志文件是否带上颜色。默认false,表示不带

    七、自定义状态码处理

    我们可以对WebServer指定的状态码进行自定义处理,例如针对常见的404/403/500等错误,我们可以展示自定义的错误信息、页面内容,或者跳转到一个特定的页面。

    我们可以使用BindStatusHandler或者BindStatusHandlerMap来实现针对指定的状态码进行自定义的回调函数处理,并且该特性也支持针对特定的域名绑定。

    我们来看几个简单的示例:

    s.BindStatusHandler(404,func(r*ghttp.Request){

    r.Response.Writeln("This is customized 404 page")

    })

    执行后,当我们访问没有绑定的路由页面,可以看到,页面显示了我们期望的返回结果:This is customized 404 page。

    s.BindStatusHandler(404,func(r*ghttp.Request){

    r.Response.RedirectTo("/status/404")

    })

    执行后,我们手动通过浏览器访问一个不存在的页面,可以看到,页面被引导跳转到了 http://127.0.0.1:8199/status/404 页面,并且可以看到页面返回内容:woops, status 404 found

    八、数据校验-校验规则

    required

    格式: required

    说明:必需参数,除了支持常见的字符串,也支持Slice/Map类型。

    示例:姓名字段Name为必需参数且不能为空。

    typeBizReqstruct{

    IDuint`v:"required"`

    Namestring`v:"required"`

    }

    email

    格式:email

    说明:EMAIL邮箱地址

    phone

    格式:phone

    说明:手机号

    phone-loose

    格式: phone

    说明:宽松的手机号验证,只要满足 13、14、15、16、17、18、19开头的11位数字都可以通过验证。

    passport

    格式: passport

    说明:通用帐号规则(字母开头,只能包含字母、数字和下划线,长度在6~18之间)。

    password

    格式: password

    说明:通用密码规则(任意可见字符,长度在6~18之间)。

    json

    格式: json

    说明:判断数据格式为JSON

    same

    格式: same:field

    说明:参数值必需与field参数的值相同

    示例:在用户注册时,提交密码Password和确认密码Password2必须相等(服务端校验)。

    typeBizReqstruct{

    Namestring`v:"required"`

    Passwordstring`v:"required|same:Password2"`

    Password2string`v:"required"`

    }

    regex

    格式: regex:pattern

    说明:参数值应当满足正则匹配规则pattern

    相关文章

      网友评论

          本文标题:Goframe框架细节

          本文链接:https://www.haomeiwen.com/subject/yoqnbrtx.html