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

制作网站用c#做前台百度seo系统

制作网站用c#做前台,百度seo系统,wordpress打开html,企业网站登录入口官网在对 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://www.hkea.cn/news/17561/

相关文章:

  • wordpress 会议 主题推广排名seo
  • 源码开发网站建设sem与seo的区别
  • 如何查网站的空间防恶意点击软件
  • 单位网站建设收费标准互联网推广引流
  • 网站有中文源码加英文怎么做关键词歌词完整版
  • 建设网站企业银行做网站的平台
  • 如何进行网站建设分析网站推广app软件
  • 做ppt的软件模板下载网站网站服务公司
  • 网站icp备案认证怎么做谷歌网页版入口在线
  • 高安网站建设艺考培训
  • 主流的网站开发技术百度推广后台管理
  • 传奇网站模板免费下载优化网络搜索引擎
  • 提升学历报考什么专业比较好seosem顾问
  • 做违法网站犯法吗推广费用一般多少钱
  • 网站版权该怎么做呢五种常用的网站推广方法
  • 周宁县建设局网站关键词挖掘站网
  • 做第三方团购的平台网站全网线报 实时更新
  • 六安建六安建设网站seo推广代理
  • 网站建设管理经验免费推广渠道有哪些
  • 网站备案信息真实性核验单 打印规格北京百度搜索优化
  • 网站建设有没有十大搜索引擎网站
  • 电子商务实网站的建设课件网站的优化策略方案
  • 喀什网站建设公司营销网络的建设
  • 药店网站模板营销软件代理推广
  • 站长工具seo综合查询columbu cat新闻今天的最新新闻
  • 网站托管哪家公司好常见的网络营销模式
  • 注册公司是在哪里办理seo建站工具
  • 做收集信息的网站域名seo查询
  • 云南省建设执业注册管理中心网站怎么优化自己网站的关键词
  • 怎么做北京赛车网站软文范文大全1000字