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

专业做蛋糕的网站网站运营岗位介绍

专业做蛋糕的网站,网站运营岗位介绍,下载手机app的软件,地方网站怎样做go web框架 gin-gonic源码解读03————middleware#xff08;context#xff09; 今天打完游戏有空整理整理之前看的gin的中间件设计#xff0c;go的中间件设计相较于前两站还是蛮简单#xff0c;蛮容易看懂的#xff0c;所以顺便把context也一起写一下。 中间件是现在w…go web框架 gin-gonic源码解读03————middlewarecontext 今天打完游戏有空整理整理之前看的gin的中间件设计go的中间件设计相较于前两站还是蛮简单蛮容易看懂的所以顺便把context也一起写一下。 中间件是现在web服务里统一化拓展最常用的功能他是为了在我们的web服务中实现一些可重复使用可组合的功能方法、可以让我们的 web逻辑在执行之前或者之后进行预处理后处理验证等操作。 在说中间件之前我们先回忆一下之前几张看过的代码的。 **gin.go** 文件中gin为了实现http.Handler接口而实现的ServeHTTP()方法 // ServeHTTP conforms to the http.Handler interface. func (engine *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request) {// 从对象池获取Context对象(对象池这里就不讲了大家可以搜博客去看这里只要大家会用就可以了)c : engine.pool.Get().(*Context)// 这三行其实就context的构造传入http.ResponseWriter,*http.Requestc.writermem.reset(w)c.Request reqc.reset()// 去我们的路由中查找响应的url并执行响应的逻辑engine.handleHTTPRequest(c)engine.pool.Put(c) } 这里再顺便给大家介绍一下contextcontext实际上就是gin框架为了统一的参数管理包装的数据结构他除了包含了我们每次访问ServeHTTP的传参(w http.ResponseWriter, req *http.Request)还包含了一些封装的web Response方法调用就返回非常好用和一些请求获取参数的方法其基本上覆盖了开发者平时所以操作需求有兴趣的同学可以自己看看 .\Go\gin\context.go 中的内容。 // 这里缩略一下只讲今天会用到的几个参数 type Context struct {writermem responseWriterRequest *http.RequestWriter ResponseWriterhandlers HandlersChain // 中间件执行链handlers index int8 // 执行下标fullPath string// 引擎的指针engine *Engine略 }我们回到正题看看我们的**handleHTTPRequest()**方法 // 去我们的路由中查找响应的url并执行响应的逻辑 engine.handleHTTPRequest( c ) 这就是我们上次手撕的那个前缀树的查找方法。而我们的目的是通过收到http请求的url来找到客户端需要请求的逻辑接口。 // 由于篇幅所限代码会有所缩略func (engine *Engine) handleHTTPRequest(c *Context) {// 很显然就是把我们请求方法和路径从Context里拿出来方便使用httpMethod : c.Request.MethodrPath : c.Request.URL.Pathunescape : false略// Find root of the tree for the given HTTP method// 这里就是我们的前缀树的t : engine.treesfor i, tl : 0, len(t); i tl; i {// 这里前面说过的引擎(engine)中存的是一个前缀树的切片([]tree)// 每个请求方法一棵树这里是遍历切片找到对应的请求方法if t[i].method ! httpMethod {continue}root : t[i].root// Find route in tree// 找到树了去树里查找value : root.getValue(rPath, c.params, c.skippedNodes, unescape)// 参数节点拿参数if value.params ! nil {c.Params *value.params}// 关键点来了这里就找到了我们要执行的逻辑方法if value.handlers ! nil {c.handlers value.handlersc.fullPath value.fullPathc.Next()c.writermem.WriteHeaderNow()return}略}break}略serveError(c, http.StatusNotFound, default404Body) }为了讲的详细的点我们把我们的关键代码单独拿出来说 c.handlers value.handlers // 1.将接口的handlers赋值给了Context的handlersc.fullPath value.fullPath // 2.给fullPath 赋值c.Next() // 3.执行Next() 方法c.writermem.WriteHeaderNow()// 4. 给HTTP response写入status codereturn步骤1的赋值给的是handlers 而不是handler这里大家可能会很奇怪我业务逻辑其实一个函数就可以解决这里为啥会缓存一个handlers呢难道我的业务函数要拆分成好几个函数来写其实这个handlers 存储的除了我们业务函数就是我们所有的中间件函数。 // HandlerFunc defines the handler used by gin middleware as return value. type HandlerFunc func(*Context)// HandlersChain defines a HandlerFunc slice. type HandlersChain []HandlerFuncgin的中间件调用的密码也都包含在步骤3里 func (c *Context) Next() {// 执行下标c.index// 一上来就自增是因为func (c *Context) reset()这个初始化方法里会把下标初始化成-1所以我们一上来就要让他变成0。// 这么做的目的就是因为我们的中间件函数中也会调用Next()for c.index int8(len(c.handlers)) {// 通过下标去执行中间件c.handlers[c.index](c)// 显然执行完了,不然就死循环了c.index} }gin的中间件调用的秘密还是蛮简单的接下来我们看看gin中间件的注册。 gin的中间件注册大家都知道engine可以使用Use路由组的RouterGroup也可以使用Use实际上engine.Use()也是调用了RouterGroup.Use(),因为我们engine的路由包括了我们所有的RouterGroup的路由。 func (engine *Engine) Use(middleware ...HandlerFunc) IRoutes {engine.RouterGroup.Use(middleware...)// 这边是初始化的时候顺便注册一些异常的处理方式// 当然为了避免重复的调用这两个rebuild40X函数这个Use还是建议一次性调用到位engine.rebuild404Handlers() engine.rebuild405Handlers()return engine }// Use adds middleware to the group, see example code in GitHub. func (group *RouterGroup) Use(middleware ...HandlerFunc) IRoutes {// 非常的简单我们的Handlers 是一个切片他把所有的middleware插入到中间件的末端group.Handlers append(group.Handlers, middleware...)return group.returnObj() }这样子就实现了我们功能强大的中间件调用链条只说这些感觉内容少了点再带大家看看gin自带的两个中间件把。 // 这是gin代码中获取默认Engine 的方法大家一定都用过 func Default() *Engine {// 无关紧要的版本校验debugPrintWARNINGDefault()// New()第一篇应该说过engine : New()// 这里调用了两个中间件Logger(), Recovery()engine.Use(Logger(), Recovery())return engine }Logger() 顾名思义很显然是打印日志的一个中间件打印日志也是中间件在开发中最有用的几个用处之一 func Logger() HandlerFunc {return LoggerWithConfig(LoggerConfig{}) }// LoggerWithConfig instance a Logger middleware with config. func LoggerWithConfig(conf LoggerConfig) HandlerFunc {// LoggerConfig不是我们本文讲解的重点大家可以自己去看看// 这下面的代码大意就是获取日志的打印格式和输出位置formatter : conf.Formatterif formatter nil {formatter defaultLogFormatter}out : conf.Outputif out nil {out DefaultWriter}notlogged : conf.SkipPathsisTerm : trueif w, ok : out.(*os.File); !ok || os.Getenv(TERM) dumb ||(!isatty.IsTerminal(w.Fd()) !isatty.IsCygwinTerminal(w.Fd())) {isTerm false}// 知识点struct{}不占内存空间// 在go语言map[string]struct{}的写法相当于创建了一个set结构体。var skip map[string]struct{}if length : len(notlogged); length 0 {skip make(map[string]struct{}, length)for _, path : range notlogged {skip[path] struct{}{}}}// 正文开始return func(c *Context) {// Start timerstart : time.Now()path : c.Request.URL.Pathraw : c.Request.URL.RawQuery// Process request// 可能很多人会好奇为什么在中间件的中间还要执行一个next// 这是一个中间件在逻辑函数执行之前还有逻辑函数执行之后都有钩子逻辑可以执行// 大家可以把这个想象成一个套娃的结构// 例如logger() 前半段logic() 业务逻辑代码logger() 后半段c.Next()// Log only when path is not being skipped// 上面英文很简单大家自己看看if _, ok : skip[path]; !ok {param : LogFormatterParams{Request: c.Request,isTerm: isTerm,Keys: c.Keys,}// Stop timer// 结构化打印然后输出到流中没啥好说的param.TimeStamp time.Now()param.Latency param.TimeStamp.Sub(start)param.ClientIP c.ClientIP()param.Method c.Request.Methodparam.StatusCode c.Writer.Status()param.ErrorMessage c.Errors.ByType(ErrorTypePrivate).String()param.BodySize c.Writer.Size()if raw ! {path path ? raw}param.Path path// 输出完了fmt.Fprint(out, formatter(param))}} } 不过一般大家的项目之中都不会用gin提供的logger中间件因为大家都有自己的日志格式不过你实在想用也可以把自己的logger实例实现gin.logger的接口然后在初始化engine的时候传给engine就好了 完
http://www.yutouwan.com/news/83709/

相关文章:

  • 关于网站建设的工作总结网站项目建设的组织机构
  • asp.net建立网站吗营销型网站有哪些建设流程
  • 珠海商城网站把百度网址大全设为首页
  • 网站开发招聘名称公司做网站 优帮云
  • wordpress图片站优化成品软件网站大全推荐
  • 网站建设考试题目郑州官方网站建设首选华苏科技
  • php网站源码架构抚顺网站建设
  • 自己做网站需要什么材料手机网站有什么要求
  • 建立一个自己的网站上海网站建设公司网站建设
  • 员工支付做网站的费用分录做网站公司价格
  • 网站认证打的钱怎么做分录公司装修会计分录
  • 衡州网站建设seo做外贸找生意上哪个网站
  • 手机设计logo软件长春网站优化教程
  • wordpress站内优化网站域名申请流程
  • 创意网站模板下载wordpress编辑媒体永久链接
  • 坦洲网站建设投资公司经营范围
  • 长沙专业的建站按效果付费wordpress后台编辑主题时提示:抱歉_该文件无法被编辑
  • 南通设计网站建设想要学做网站
  • 福州营销网站建设技术产品开发项目管理全流程
  • 谁会在阿里云建网站M97 网站建设网络公司整站源码
  • 网站建设开发感悟做破解网站合法
  • 河南省住房城乡和建设厅网站南通市城乡和住房建设局网站
  • 赞叹天河网站建设公司重庆工程建设标准化信息网
  • 网站建设合同规范室内设计师的网站
  • 织梦网站后台空白怎么建设境外网站
  • 东营市两学一做考试网站网站前端工程师
  • asp网站镜像代码wordpress+手册主题
  • 企业建设网站作用wordpress主题雪人yeti1.9.2
  • 我是做网站怎么赚钱吗福建宏盛建设集团网站
  • 直接进网站的浏览器打开wordpress短链识别