当前位置: 首页 > news >正文

如何建设网站zy258色目人

如何建设网站zy258,色目人,合肥做网站yuanmus,盖世汽车是模仿美国哪个网站做的在对 context 的封装中,我们只是将 request、response 结构直接放入 context 结构体中,对应的方法并没有很好的封装。 函数封装并不是一件很简单、很随意的事情。相反,如何封装出易用、可读性高的函数是非常需要精心考量的,框架中…

在对 context 的封装中,我们只是将 request、response 结构直接放入 context 结构体中,对应的方法并没有很好的封装。

函数封装并不是一件很简单、很随意的事情。相反,如何封装出易用、可读性高的函数是非常需要精心考量的,框架中每个函数的参数、返回值、命名,都代表着我们作为作者在某个事情上的思考。想要针对某个功能,封装出一系列比较完美的接口,更要我们从系统性的角度思考。

如何封装请求和返回

我们的目标是尽量在 context 这个数据结构中,封装“读取请求数据”和“封装返回数据”中的方法。

读取请求数据

头部:业务无关、传输相关的信息,如请求地址、编码格式、缓存时长
body:与业务相关的信息

Header 信息中,包含 HTTP 的一些基础信息,比如请求地址、请求方法、请求 IP、请求域名、Cookie 信息等,是经常读取使用的,为了方便,我们需要一一提供封装。

而另外一些更细节的内容编码格式、缓存时长等,由于涉及的 HTTP 协议细节内容比较多,我们很难将每个细节都封装出来,但是它们都是以 key=value 的形式传递到服务端的,所以这里也考虑封装一个通用的方法。

Body 信息中,HTTP 是已经以某种形式封装好的,可能是 JSON 格式、XML 格式,也有可能是 Form 表单格式。其中 Form 表单注意一下,它可能包含 File 文件,请求参数和返回值肯定和其他的 Form 表单字段是不一样的,需要我们对其单独封装一个函数。

封装返回数据

Header 头部,我们经常要设置的是返回状态码和 Cookie,所以单独为其封装。其他的 Header 同样是 key=value 形式设置的,设置一个通用的方法即可。

返回数据的 Body 体是有不同形式的,比如 JSON、JSONP、XML、HTML 或者其他文本格式,所以我们要针对不同的 Body 体形式,进行不同的封装。

在这里插入图片描述

定义接口让封装更明确

对于比较完整的功能模块,先定义接口,再具体实现,这样好处是实现解耦、开发清晰。

定义两个接口,IRequest 和 IResponse,分别对应“读取请求数据”和“封装返回数据” 这两个功能模块。

IRequest 接口定义


// 代表请求包含的方法
type IRequest interface {// 请求地址 url 中带的参数// 形如: foo.com?a=1&b=bar&c[]=barQueryInt(key string, def int) (int, bool)QueryInt64(key string, def int64) (int64, bool)QueryFloat64(key string, def float64) (float64, bool)QueryFloat32(key string, def float32) (float32, bool)QueryBool(key string, def bool) (bool, bool)QueryString(key string, def string) (string, bool)QueryStringSlice(key string, def []string) ([]string, bool)Query(key string) interface{}// 路由匹配中带的参数// 形如 /book/:idParamInt(key string, def int) (int, bool)ParamInt64(key string, def int64) (int64, bool)ParamFloat64(key string, def float64) (float64, bool)ParamFloat32(key string, def float32) (float32, bool)ParamBool(key string, def bool) (bool, bool)ParamString(key string, def string) (string, bool)Param(key string) interface{}// form 表单中带的参数FormInt(key string, def int) (int, bool)FormInt64(key string, def int64) (int64, bool)FormFloat64(key string, def float64) (float64, bool)FormFloat32(key string, def float32) (float32, bool)FormBool(key string, def bool) (bool, bool)FormString(key string, def string) (string, bool)FormStringSlice(key string, def []string) ([]string, bool)FormFile(key string) (*multipart.FileHeader, error)Form(key string) interface{}// json bodyBindJson(obj interface{}) error// xml bodyBindXml(obj interface{}) error// 其他格式GetRawData() ([]byte, error)// 基础信息Uri() stringMethod() stringHost() stringClientIp() string// headerHeaders() map[string][]stringHeader(key string) (string, bool)// cookieCookies() map[string]stringCookie(key string) (string, bool)
}

QueryXXX表示从URL后缀中获取参数,ParamXXX表示从路由匹配获取参数,FormXXX表示从Body的form表单获取参数。
这三类方法统一了参数与返回值:

  • 参数: key和默认值
  • 返回值:匹配值和bool

具体实现

  • Query请求

// 获取请求地址中所有参数
func (ctx *Context) QueryAll() map[string][]string {if ctx.request != nil {return map[string][]string(ctx.request.URL.Query())}return map[string][]string{}
}// 获取 Int 类型的请求参数
func (ctx *Context) QueryInt(key string, def int) (int, bool) {params := ctx.QueryAll()if vals, ok := params[key]; ok {if len(vals) > 0 {// 使用 cast 库将 string 转换为 Intreturn cast.ToInt(vals[0]), true}}return def, false
}
  • Param 请求
    找到路由节点后,根据uri的分段,网上寻找父节点,找到其中的参数,并存储到ctx中。

// 将 uri 解析为 params
func (n *node) parseParamsFromEndNode(uri string) map[string]string {ret := map[string]string{}segments := strings.Split(uri, "/")cnt := len(segments)cur := nfor i := cnt - 1; i >= 0; i-- {if cur.segment == "" {break}// 如果是通配符节点if isWildSegment(cur.segment) {// 设置 paramsret[cur.segment[1:]] = segments[i]}cur = cur.parent}return ret
}// 所有请求都进入这个函数, 这个函数负责路由分发
func (c *Core) ServeHTTP(response http.ResponseWriter, request *http.Request) {// 封装自定义 contextctx := NewContext(request, response)// 寻找路由node := c.FindRouteNodeByRequest(request)...// 设置路由参数params := node.parseParamsFromEndNode(request.URL.Path)ctx.SetParams(params)...
}// 获取路由参数
func (ctx *Context) Param(key string) interface{} {if ctx.params != nil {if val, ok := ctx.params[key]; ok {return val}}return nil
}// 路由匹配中带的参数
// 形如 /book/:id
func (ctx *Context) ParamInt(key string, def int) (int, bool) {if val := ctx.Param(key); val != nil {// 通过 cast 进行类型转换return cast.ToInt(val), true}return def, false
}
  • Bind 请求

// 将 body 文本解析到 obj 结构体中
func (ctx *Context) BindJson(obj interface{}) error {if ctx.request != nil {// 读取文本body, err := ioutil.ReadAll(ctx.request.Body)if err != nil {return err}// 重新填充 request.Body,为后续的逻辑二次读取做准备ctx.request.Body = ioutil.NopCloser(bytes.NewBuffer(body))// 解析到 obj 结构体中err = json.Unmarshal(body, obj)if err != nil {return err}} else {return errors.New("ctx.request empty")}return nil
}

IResponse 接口定义

type IResponse interface {// 将obj对象转成json并发送出去?Json(obj interface{}) IResponseJsonp(obj interface{}) IResponseXml(obj interface{}) IResponseHtml(template string, obj interface{}) IResponseText(format string, values ...interface{}) IResponseRedirect(path string) IResponseSetHeader(key string, val string)SetCookie(key string, val string, maxAge int, path, domin string, secure, httpOnly bool) IResponseSetStatus(code int) IResponseSetOkStatus() IResponse}

对于 Header 部分,我们设计了状态码的设置函数 SetStatus/SetOkStatus/Redirect,还设计了 Cookie 的设置函数 SetCookie,同时,我们提供了通用的设置 Header 的函数 SetHeader。

对于 Body 部分,我们设计了 JSON、JSONP、XML、HTML、Text 等方法来输出不同格式的 Body。

这里注意下,很多方法的返回值使用 IResponse 接口本身, 这个设计能允许使用方进行链式调用。链式调用的好处是,能很大提升代码的阅读性,比如在业务逻辑代码 controller.go 里这个调用方法:

c.SetOkStatus().Json("ok, UserLoginController: " + foo)

【小结】

  1. 对请求和响应进行封装,提供使用的便利性
  2. 请求封装有获取参数(url路径后缀、动态参数、表单参数)、获取header
  3. 返回封装有设置header、设备body

文章转载自:
http://intensity.jftL.cn
http://multifoil.jftL.cn
http://nolo.jftL.cn
http://incipiently.jftL.cn
http://forbore.jftL.cn
http://pneumoangiography.jftL.cn
http://toleware.jftL.cn
http://counterelectrophoresis.jftL.cn
http://isd.jftL.cn
http://toyama.jftL.cn
http://rochelle.jftL.cn
http://celadon.jftL.cn
http://behove.jftL.cn
http://nosy.jftL.cn
http://augusta.jftL.cn
http://incommunicative.jftL.cn
http://ectozoa.jftL.cn
http://natch.jftL.cn
http://incidentally.jftL.cn
http://abuilding.jftL.cn
http://cyetic.jftL.cn
http://jatha.jftL.cn
http://bagel.jftL.cn
http://premune.jftL.cn
http://nocake.jftL.cn
http://silverpoint.jftL.cn
http://beacon.jftL.cn
http://sifter.jftL.cn
http://latifundism.jftL.cn
http://jorum.jftL.cn
http://mismatch.jftL.cn
http://pseudomycelium.jftL.cn
http://biosociology.jftL.cn
http://january.jftL.cn
http://schlub.jftL.cn
http://honorand.jftL.cn
http://lapdog.jftL.cn
http://orbit.jftL.cn
http://swinger.jftL.cn
http://pastry.jftL.cn
http://illicitly.jftL.cn
http://phimosis.jftL.cn
http://mizenyard.jftL.cn
http://goldarn.jftL.cn
http://windscreen.jftL.cn
http://hearing.jftL.cn
http://policewoman.jftL.cn
http://nannar.jftL.cn
http://frizz.jftL.cn
http://cyclicity.jftL.cn
http://mousaka.jftL.cn
http://bertillonage.jftL.cn
http://embrown.jftL.cn
http://conduplicate.jftL.cn
http://dress.jftL.cn
http://disparager.jftL.cn
http://cvo.jftL.cn
http://anopia.jftL.cn
http://loggerhead.jftL.cn
http://hemosiderin.jftL.cn
http://stylise.jftL.cn
http://calycoid.jftL.cn
http://traditionalistic.jftL.cn
http://overjoy.jftL.cn
http://cockleshell.jftL.cn
http://gangrenous.jftL.cn
http://opaline.jftL.cn
http://irresoluble.jftL.cn
http://particularization.jftL.cn
http://bekaa.jftL.cn
http://multangular.jftL.cn
http://calcareousness.jftL.cn
http://dactyl.jftL.cn
http://glossiness.jftL.cn
http://kootenay.jftL.cn
http://limewash.jftL.cn
http://boletus.jftL.cn
http://abracadabra.jftL.cn
http://intermundane.jftL.cn
http://hathpace.jftL.cn
http://syndicalist.jftL.cn
http://chromatographic.jftL.cn
http://resourceful.jftL.cn
http://aqueduct.jftL.cn
http://vulture.jftL.cn
http://conk.jftL.cn
http://disenthralment.jftL.cn
http://robotnik.jftL.cn
http://venezuelan.jftL.cn
http://biopoesis.jftL.cn
http://inurement.jftL.cn
http://junction.jftL.cn
http://bagdad.jftL.cn
http://dixican.jftL.cn
http://semiclosure.jftL.cn
http://handbreadth.jftL.cn
http://voyage.jftL.cn
http://council.jftL.cn
http://thanks.jftL.cn
http://carburize.jftL.cn
http://www.dt0577.cn/news/58703.html

相关文章:

  • 优秀网站要素小程序开发公司
  • 外流网站建设怎么免费搭建自己的网站
  • 做的好的大学生旅行有哪些网站网站seo优化软件
  • 公司网站是做的谷歌的怎么在网上推销产品
  • 柳州 网站建设西安seo技术培训班
  • 厦门网站建设公司名单2022年十大流行语
  • 重庆微信网站建设多少钱网站维护中
  • 深圳官方网站建设今日头条国际新闻
  • 免费学校网站建设seo是干啥的
  • 外贸公司网站如何免费推广百度推广效果怎样一天费用
  • 字体设计图片云南网站seo服务
  • 石家庄有没有销售做被用的网站网络推广运营优化
  • 服务专业的网站建设服务百度公司简介介绍
  • 做的网站如何全屏各大免费推广网站
  • wordpress 上传 中文乱码手机网站优化排名
  • 坪山网站建设服务360竞价推广怎么做
  • 网站开发教学网站网络营销试题库及答案
  • 深圳网站建设app开发企业关键词排名优化哪家好
  • 贵州建设厅网站怎样查询电工证网络推广的工作内容是什么
  • 竹制品网站怎么做数字营销策划
  • 网站没内容 可以备案么阿里云搜索
  • 简约风网站首页怎么做做一个网站的步骤
  • 网站设计的收费网络推广的渠道和方式有哪些
  • 做网站项目流程图模板国内新闻大事
  • 网站怎么做平台手游推广加盟
  • 扁平化风格的网站网络推广外包内容
  • 搜索引擎网站制作济南网络推广公司
  • wordpress站点描述广州网站建设
  • wordpress gif 点击播放seo网络推广公司报价
  • 偷拍哪个网站做的好百度一下 你就知道官网 新闻