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

网站建设服务器怎么设置WordPress node

网站建设服务器怎么设置,WordPress node,做一个网站需要多少钱大概,h5网站开发软件文章目录 定义中间件前置中间件后置中间件路由级别中间件 定义中间件 中间件的作用是给应用添加一些额外的功能#xff0c;但是不会影响原有应用的编码方式#xff0c;想用的时候直接添加#xff0c;不想用的时候也可以轻松去除#xff0c;实现所谓的可插拔。中间件的实现… 文章目录 定义中间件前置中间件后置中间件路由级别中间件 定义中间件 中间件的作用是给应用添加一些额外的功能但是不会影响原有应用的编码方式想用的时候直接添加不想用的时候也可以轻松去除实现所谓的可插拔。中间件的实现位置在哪里 不能耦合在用户的代码中需要独立存在但是又能拿到上下文并作出影响位置在处理器的前后 注意中间件是一个调用链条所以在处理真正的业务之前可能会经过多个中间件。 // 定义中间件 type MiddlewareFunc func(handleFunc HandleFunc) HandleFunc前置中间件 // zj.gopackage zjgoimport (fmtlognet/http )const ANY ANY// 定义处理响应函数 type HandleFunc func(ctx *Context)// 定义中间件 type MiddlewareFunc func(handleFunc HandleFunc) HandleFunc// 抽象出路由的概念 type routerGroup struct {name string // 组名handleFuncMap map[string]map[string]HandleFunc // 映射关系应该由每个路由组去维护handlerMethodMap map[string][]string // 记录GETPOST等请求方式所记录的路由实现对同一路由不同请求方式的支持TreeNode *TreeNode // 记录该路由组下的路由前缀树preMiddlewares []MiddlewareFunc // 定义前置中间件postMiddlewares []MiddlewareFunc // 定义后置中间件 }// 增加前置中间件 func (routerGroup *routerGroup) PreHandle(middlewareFunc ...MiddlewareFunc) { // 在Go语言中函数参数中的三个点...表示可变参数variadic parameter允许函数接受不定数量的同类型参数。routerGroup.preMiddlewares append(routerGroup.preMiddlewares, middlewareFunc...) }// 增加后置中间件 func (routerGroup *routerGroup) PostHandle(middlewareFunc ...MiddlewareFunc) {routerGroup.postMiddlewares append(routerGroup.postMiddlewares, middlewareFunc...) }func (routerGroup *routerGroup) methodHandle(handle HandleFunc, ctx *Context) {// 执行前置中间件if routerGroup.preMiddlewares ! nil {for _, middlewareFunc : range routerGroup.preMiddlewares {handle middlewareFunc(handle)}}handle(ctx)// 执行后置中间件}// 定义路由结构体 type router struct {routerGroups []*routerGroup // 路由下面应该维护着不同的组 }// 添加路由组 func (r *router) Group(name string) *routerGroup {routerGroup : routerGroup{name: name,handleFuncMap: make(map[string]map[string]HandleFunc),handlerMethodMap: make(map[string][]string),TreeNode: TreeNode{name: /, children: make([]*TreeNode, 0)},}r.routerGroups append(r.routerGroups, routerGroup)return routerGroup }// 给路由结构体添加一个添加路由功能的函数 // func (routerGroup *routerGroup) Add(name string, handleFunc HandleFunc) { // routerGroup.handleFuncMap[name] handleFunc // }// 由于 ANY POST GET 都需要重复相同的逻辑代码所以做一个提取操作 func (routerGroup *routerGroup) handleRequest(name string, method string, handleFunc HandleFunc) {if _, exist : routerGroup.handleFuncMap[name]; !exist {routerGroup.handleFuncMap[name] make(map[string]HandleFunc)}if _, exist : routerGroup.handleFuncMap[name][method]; !exist {routerGroup.handleFuncMap[name][method] handleFuncrouterGroup.handlerMethodMap[method] append(routerGroup.handlerMethodMap[method], name)} else {panic(Under the same route, duplication is not allowed!!!)}routerGroup.TreeNode.Put(name) }// Any代表支持任意的请求方式 func (routerGroup *routerGroup) Any(name string, handleFunc HandleFunc) {routerGroup.handleRequest(name, ANY, handleFunc) }// POST代表支持POST请求方式 func (routerGroup *routerGroup) Post(name string, handleFunc HandleFunc) {routerGroup.handleRequest(name, http.MethodPost, handleFunc) }// GET代表支持GET请求方式 func (routerGroup *routerGroup) Get(name string, handleFunc HandleFunc) {routerGroup.handleRequest(name, http.MethodGet, handleFunc) }// DELETE代表支持DELETE请求方式 func (routerGroup *routerGroup) Delete(name string, handleFunc HandleFunc) {routerGroup.handleRequest(name, http.MethodDelete, handleFunc) }// PUT代表支持PUT请求方式 func (routerGroup *routerGroup) Put(name string, handleFunc HandleFunc) {routerGroup.handleRequest(name, http.MethodPut, handleFunc) }// PATCH代表支持PATCH请求方式 func (routerGroup *routerGroup) Patch(name string, handleFunc HandleFunc) {routerGroup.handleRequest(name, http.MethodPatch, handleFunc) }// 只要实现 ServeHTTP 这个方法就相当于实现了对应的 HTTP 处理器 // 结构体 Engine 实现了 ServeHTTP(w http.ResponseWriter, r *http.Request) 方法 // 所以它就自动实现了 http.Handler 接口因此可以直接被用于 http.ListenAndServe // Engine 实现了 ServeHTTP它就是一个合法的 http.Handler可以用 http.Handle 来绑定它到某个具体的路由路径上 func (e *Engine) ServeHTTP(w http.ResponseWriter, r *http.Request) {e.httpRequestHandle(w, r) }func (e *Engine) httpRequestHandle(w http.ResponseWriter, r *http.Request) {// 在 Go 的 net/http 包中r *http.Request 代表了客户端发来的 HTTP 请求对象。// 可以通过 r.Method 来获取这次请求使用的是什么方法Method例如GET、POST、PUT、DELETE 等。if r.Method http.MethodGet {fmt.Fprintf(w, 这是一个 GET 请求!!! )} else if r.Method http.MethodPost {fmt.Fprintf(w, 这是一个 POST 请求!!! )} else {fmt.Fprintf(w, 这是一个其他类型的请求%s!!! , r.Method)}for _, group : range e.routerGroups {routerName : SubStringLast(r.RequestURI, /group.name)if node : group.TreeNode.Get(routerName); node ! nil node.isEnd {// 路由匹配上了ctx : Context{W: w, R: r}// 先判断当前请求路由是否支持任意请求方式的Anyif handle, exist : group.handleFuncMap[node.routerName][ANY]; exist {group.methodHandle(handle, ctx)return}// 不支持 Any去该请求所对应的请求方式对应的 Map 里面去找是否有对应的路由if handle, exist : group.handleFuncMap[node.routerName][r.Method]; exist {group.methodHandle(handle, ctx)return}// 没找到对应的路由说明该请求方式不允许w.WriteHeader(http.StatusMethodNotAllowed)fmt.Fprintf(w, %s %s not allowed!!!\n, r.Method, r.RequestURI)return}}w.WriteHeader(http.StatusNotFound)fmt.Fprintf(w, %s %s not found!!!\n, r.Method, r.RequestURI)return }// 定义一个引擎结构体 type Engine struct {router }// 引擎结构体的初始化方法 func New() *Engine {return Engine{router: router{},} }// 引擎的启动方法 func (e *Engine) Run() {// for _, group : range e.routerGroups {// for name, value : range group.handleFuncMap {// http.HandleFunc(/group.namename, value)// }// }// 把 e 这个http处理器绑定到对应路由下http.Handle(/, e)err : http.ListenAndServe(:3986, nil)if err ! nil {log.Fatal(err)} }// main.gopackage mainimport (fmtnet/httpgithub.com/ErizJ/ZJGo/zjgo )func main() {fmt.Println(Hello World!)// // 注册 HTTP 路由 /hello// http.HandleFunc(/hello, func(w http.ResponseWriter, r *http.Request) {// fmt.Fprintf(w, Hello Go!)// })// // 启动 HTTP 服务器// err : http.ListenAndServe(8111, nil)// if err ! nil {// log.Fatal(err)// }engine : zjgo.New()g1 : engine.Group(user)g1.PreHandle(func(handleFunc zjgo.HandleFunc) zjgo.HandleFunc {return func(ctx *zjgo.Context) {fmt.Println(Pre Middleware ON!!!)handleFunc(ctx)}})g1.Get(/hello, func(ctx *zjgo.Context) {fmt.Fprintf(ctx.W, http.MethodGet Hello Go!——user/hello)})// 浏览器地址栏输入的都是 GET 请求// 需要用 curl 或 Postman 来发一个真正的 POST 请求才会命中 Post handlerg1.Post(/info, func(ctx *zjgo.Context) {fmt.Println(HandleFunc ON!!!)fmt.Fprintf(ctx.W, http.MethodPost Hello Go!——user/info——POST)})g1.Get(/info, func(ctx *zjgo.Context) {fmt.Println(HandleFunc ON!!!)fmt.Fprintf(ctx.W, http.MethodGet Hello Go!——user/info——GET)})g1.Get(/get/:id, func(ctx *zjgo.Context) {fmt.Println(HandleFunc ON!!!)fmt.Fprintf(ctx.W, http.MethodGet Hello Go!——user/get/:id——GET)})g1.Get(/isEnd/get, func(ctx *zjgo.Context) {fmt.Println(HandleFunc ON!!!)fmt.Fprintf(ctx.W, http.MethodGet Hello Go!——user/isEnd/get——GET)})// 只要路由匹配就会执行对应的处理函数g1.Any(/any, func(ctx *zjgo.Context) {fmt.Fprintf(ctx.W, Hello Go!——user/any)})// g2 : engine.Group(order)// g2.Add(/hello, func(w http.ResponseWriter, r *http.Request) {// fmt.Fprintf(w, Hello Go!——order/hello)// })// g2.Add(/info, func(w http.ResponseWriter, r *http.Request) {// fmt.Fprintf(w, Hello Go!——order/info)// })fmt.Println(Starting...)engine.Run()}后置中间件 // zj.gopackage zjgoimport (fmtlognet/http )const ANY ANY// 定义处理响应函数 type HandleFunc func(ctx *Context)// 定义中间件 type MiddlewareFunc func(handleFunc HandleFunc) HandleFunc// 抽象出路由的概念 type routerGroup struct {name string // 组名handleFuncMap map[string]map[string]HandleFunc // 映射关系应该由每个路由组去维护handlerMethodMap map[string][]string // 记录GETPOST等请求方式所记录的路由实现对同一路由不同请求方式的支持TreeNode *TreeNode // 记录该路由组下的路由前缀树preMiddlewares []MiddlewareFunc // 定义前置中间件postMiddlewares []MiddlewareFunc // 定义后置中间件 }// 增加前置中间件 func (routerGroup *routerGroup) PreHandle(middlewareFunc ...MiddlewareFunc) { // 在Go语言中函数参数中的三个点...表示可变参数variadic parameter允许函数接受不定数量的同类型参数。routerGroup.preMiddlewares append(routerGroup.preMiddlewares, middlewareFunc...) }// 增加后置中间件 func (routerGroup *routerGroup) PostHandle(middlewareFunc ...MiddlewareFunc) {routerGroup.postMiddlewares append(routerGroup.postMiddlewares, middlewareFunc...) }func (routerGroup *routerGroup) methodHandle(handle HandleFunc, ctx *Context) {// 执行前置中间件if routerGroup.preMiddlewares ! nil {for _, middlewareFunc : range routerGroup.preMiddlewares {handle middlewareFunc(handle) // 难以理解的话可以看作语句叠加}}handle(ctx)// 执行后置中间件if routerGroup.postMiddlewares ! nil {for _, middlewareFunc : range routerGroup.postMiddlewares {handle middlewareFunc(handle)}}handle(ctx) }// 定义路由结构体 type router struct {routerGroups []*routerGroup // 路由下面应该维护着不同的组 }// 添加路由组 func (r *router) Group(name string) *routerGroup {routerGroup : routerGroup{name: name,handleFuncMap: make(map[string]map[string]HandleFunc),handlerMethodMap: make(map[string][]string),TreeNode: TreeNode{name: /, children: make([]*TreeNode, 0)},}r.routerGroups append(r.routerGroups, routerGroup)return routerGroup }// 给路由结构体添加一个添加路由功能的函数 // func (routerGroup *routerGroup) Add(name string, handleFunc HandleFunc) { // routerGroup.handleFuncMap[name] handleFunc // }// 由于 ANY POST GET 都需要重复相同的逻辑代码所以做一个提取操作 func (routerGroup *routerGroup) handleRequest(name string, method string, handleFunc HandleFunc) {if _, exist : routerGroup.handleFuncMap[name]; !exist {routerGroup.handleFuncMap[name] make(map[string]HandleFunc)}if _, exist : routerGroup.handleFuncMap[name][method]; !exist {routerGroup.handleFuncMap[name][method] handleFuncrouterGroup.handlerMethodMap[method] append(routerGroup.handlerMethodMap[method], name)} else {panic(Under the same route, duplication is not allowed!!!)}routerGroup.TreeNode.Put(name) }// Any代表支持任意的请求方式 func (routerGroup *routerGroup) Any(name string, handleFunc HandleFunc) {routerGroup.handleRequest(name, ANY, handleFunc) }// POST代表支持POST请求方式 func (routerGroup *routerGroup) Post(name string, handleFunc HandleFunc) {routerGroup.handleRequest(name, http.MethodPost, handleFunc) }// GET代表支持GET请求方式 func (routerGroup *routerGroup) Get(name string, handleFunc HandleFunc) {routerGroup.handleRequest(name, http.MethodGet, handleFunc) }// DELETE代表支持DELETE请求方式 func (routerGroup *routerGroup) Delete(name string, handleFunc HandleFunc) {routerGroup.handleRequest(name, http.MethodDelete, handleFunc) }// PUT代表支持PUT请求方式 func (routerGroup *routerGroup) Put(name string, handleFunc HandleFunc) {routerGroup.handleRequest(name, http.MethodPut, handleFunc) }// PATCH代表支持PATCH请求方式 func (routerGroup *routerGroup) Patch(name string, handleFunc HandleFunc) {routerGroup.handleRequest(name, http.MethodPatch, handleFunc) }// 只要实现 ServeHTTP 这个方法就相当于实现了对应的 HTTP 处理器 // 结构体 Engine 实现了 ServeHTTP(w http.ResponseWriter, r *http.Request) 方法 // 所以它就自动实现了 http.Handler 接口因此可以直接被用于 http.ListenAndServe // Engine 实现了 ServeHTTP它就是一个合法的 http.Handler可以用 http.Handle 来绑定它到某个具体的路由路径上 func (e *Engine) ServeHTTP(w http.ResponseWriter, r *http.Request) {e.httpRequestHandle(w, r) }func (e *Engine) httpRequestHandle(w http.ResponseWriter, r *http.Request) {// 在 Go 的 net/http 包中r *http.Request 代表了客户端发来的 HTTP 请求对象。// 可以通过 r.Method 来获取这次请求使用的是什么方法Method例如GET、POST、PUT、DELETE 等。if r.Method http.MethodGet {fmt.Fprintf(w, 这是一个 GET 请求!!! )} else if r.Method http.MethodPost {fmt.Fprintf(w, 这是一个 POST 请求!!! )} else {fmt.Fprintf(w, 这是一个其他类型的请求%s!!! , r.Method)}for _, group : range e.routerGroups {routerName : SubStringLast(r.RequestURI, /group.name)if node : group.TreeNode.Get(routerName); node ! nil node.isEnd {// 路由匹配上了ctx : Context{W: w, R: r}// 先判断当前请求路由是否支持任意请求方式的Anyif handle, exist : group.handleFuncMap[node.routerName][ANY]; exist {group.methodHandle(handle, ctx)return}// 不支持 Any去该请求所对应的请求方式对应的 Map 里面去找是否有对应的路由if handle, exist : group.handleFuncMap[node.routerName][r.Method]; exist {group.methodHandle(handle, ctx)return}// 没找到对应的路由说明该请求方式不允许w.WriteHeader(http.StatusMethodNotAllowed)fmt.Fprintf(w, %s %s not allowed!!!\n, r.Method, r.RequestURI)return}}w.WriteHeader(http.StatusNotFound)fmt.Fprintf(w, %s %s not found!!!\n, r.Method, r.RequestURI)return }// 定义一个引擎结构体 type Engine struct {router }// 引擎结构体的初始化方法 func New() *Engine {return Engine{router: router{},} }// 引擎的启动方法 func (e *Engine) Run() {// for _, group : range e.routerGroups {// for name, value : range group.handleFuncMap {// http.HandleFunc(/group.namename, value)// }// }// 把 e 这个http处理器绑定到对应路由下http.Handle(/, e)err : http.ListenAndServe(:3986, nil)if err ! nil {log.Fatal(err)} }// main.gopackage mainimport (fmtnet/httpgithub.com/ErizJ/ZJGo/zjgo )func main() {fmt.Println(Hello World!)// // 注册 HTTP 路由 /hello// http.HandleFunc(/hello, func(w http.ResponseWriter, r *http.Request) {// fmt.Fprintf(w, Hello Go!)// })// // 启动 HTTP 服务器// err : http.ListenAndServe(8111, nil)// if err ! nil {// log.Fatal(err)// }engine : zjgo.New()g1 : engine.Group(user)g1.PreHandle(func(handleFunc zjgo.HandleFunc) zjgo.HandleFunc {return func(ctx *zjgo.Context) {fmt.Println(Pre Middleware ON!!!)handleFunc(ctx)}})g1.PostHandle(func(handleFunc zjgo.HandleFunc) zjgo.HandleFunc {return func(ctx *zjgo.Context) {fmt.Println(Post Middleware ON!!!)}})g1.Get(/hello, func(ctx *zjgo.Context) {fmt.Fprintf(ctx.W, http.MethodGet Hello Go!——user/hello)})// 浏览器地址栏输入的都是 GET 请求// 需要用 curl 或 Postman 来发一个真正的 POST 请求才会命中 Post handlerg1.Post(/info, func(ctx *zjgo.Context) {fmt.Println(HandleFunc ON!!!)fmt.Fprintf(ctx.W, http.MethodPost Hello Go!——user/info——POST)})g1.Get(/info, func(ctx *zjgo.Context) {fmt.Println(HandleFunc ON!!!)fmt.Fprintf(ctx.W, http.MethodGet Hello Go!——user/info——GET)})g1.Get(/get/:id, func(ctx *zjgo.Context) {fmt.Println(HandleFunc ON!!!)fmt.Fprintf(ctx.W, http.MethodGet Hello Go!——user/get/:id——GET)})g1.Get(/isEnd/get, func(ctx *zjgo.Context) {fmt.Println(HandleFunc ON!!!)fmt.Fprintf(ctx.W, http.MethodGet Hello Go!——user/isEnd/get——GET)})// 只要路由匹配就会执行对应的处理函数g1.Any(/any, func(ctx *zjgo.Context) {fmt.Fprintf(ctx.W, Hello Go!——user/any)})// g2 : engine.Group(order)// g2.Add(/hello, func(w http.ResponseWriter, r *http.Request) {// fmt.Fprintf(w, Hello Go!——order/hello)// })// g2.Add(/info, func(w http.ResponseWriter, r *http.Request) {// fmt.Fprintf(w, Hello Go!——order/info)// })fmt.Println(Starting...)engine.Run()}但是这里前置和后置中间件似乎有点多余了因为在前置中间件中执行完一系列前置中间件和主体业务函数后就可以执行后置中间件了不用其他冗余代码。 // zj.gopackage zjgoimport (fmtlognet/http )const ANY ANY// 定义处理响应函数 type HandleFunc func(ctx *Context)// 定义中间件 type MiddlewareFunc func(handleFunc HandleFunc) HandleFunc// 抽象出路由的概念 type routerGroup struct {name string // 组名handleFuncMap map[string]map[string]HandleFunc // 映射关系应该由每个路由组去维护handlerMethodMap map[string][]string // 记录GETPOST等请求方式所记录的路由实现对同一路由不同请求方式的支持TreeNode *TreeNode // 记录该路由组下的路由前缀树middlewares []MiddlewareFunc // 定义中间件 }// 增加中间件 func (routerGroup *routerGroup) UseMiddleware(middlewareFunc ...MiddlewareFunc) { // 在Go语言中函数参数中的三个点...表示可变参数variadic parameter允许函数接受不定数量的同类型参数。routerGroup.middlewares append(routerGroup.middlewares, middlewareFunc...) }func (routerGroup *routerGroup) methodHandle(handle HandleFunc, ctx *Context) {// 执行通用中间件任何路由组都可以执行该方法if routerGroup.middlewares ! nil {for _, middlewareFunc : range routerGroup.middlewares {handle middlewareFunc(handle) // 难以理解的话可以看作语句叠加}}handle(ctx) }// 定义路由结构体 type router struct {routerGroups []*routerGroup // 路由下面应该维护着不同的组 }// 添加路由组 func (r *router) Group(name string) *routerGroup {routerGroup : routerGroup{name: name,handleFuncMap: make(map[string]map[string]HandleFunc),handlerMethodMap: make(map[string][]string),TreeNode: TreeNode{name: /, children: make([]*TreeNode, 0)},}r.routerGroups append(r.routerGroups, routerGroup)return routerGroup }// 给路由结构体添加一个添加路由功能的函数 // func (routerGroup *routerGroup) Add(name string, handleFunc HandleFunc) { // routerGroup.handleFuncMap[name] handleFunc // }// 由于 ANY POST GET 都需要重复相同的逻辑代码所以做一个提取操作 func (routerGroup *routerGroup) handleRequest(name string, method string, handleFunc HandleFunc) {if _, exist : routerGroup.handleFuncMap[name]; !exist {routerGroup.handleFuncMap[name] make(map[string]HandleFunc)}if _, exist : routerGroup.handleFuncMap[name][method]; !exist {routerGroup.handleFuncMap[name][method] handleFuncrouterGroup.handlerMethodMap[method] append(routerGroup.handlerMethodMap[method], name)} else {panic(Under the same route, duplication is not allowed!!!)}routerGroup.TreeNode.Put(name) }// Any代表支持任意的请求方式 func (routerGroup *routerGroup) Any(name string, handleFunc HandleFunc) {routerGroup.handleRequest(name, ANY, handleFunc) }// POST代表支持POST请求方式 func (routerGroup *routerGroup) Post(name string, handleFunc HandleFunc) {routerGroup.handleRequest(name, http.MethodPost, handleFunc) }// GET代表支持GET请求方式 func (routerGroup *routerGroup) Get(name string, handleFunc HandleFunc) {routerGroup.handleRequest(name, http.MethodGet, handleFunc) }// DELETE代表支持DELETE请求方式 func (routerGroup *routerGroup) Delete(name string, handleFunc HandleFunc) {routerGroup.handleRequest(name, http.MethodDelete, handleFunc) }// PUT代表支持PUT请求方式 func (routerGroup *routerGroup) Put(name string, handleFunc HandleFunc) {routerGroup.handleRequest(name, http.MethodPut, handleFunc) }// PATCH代表支持PATCH请求方式 func (routerGroup *routerGroup) Patch(name string, handleFunc HandleFunc) {routerGroup.handleRequest(name, http.MethodPatch, handleFunc) }// 只要实现 ServeHTTP 这个方法就相当于实现了对应的 HTTP 处理器 // 结构体 Engine 实现了 ServeHTTP(w http.ResponseWriter, r *http.Request) 方法 // 所以它就自动实现了 http.Handler 接口因此可以直接被用于 http.ListenAndServe // Engine 实现了 ServeHTTP它就是一个合法的 http.Handler可以用 http.Handle 来绑定它到某个具体的路由路径上 func (e *Engine) ServeHTTP(w http.ResponseWriter, r *http.Request) {e.httpRequestHandle(w, r) }func (e *Engine) httpRequestHandle(w http.ResponseWriter, r *http.Request) {// 在 Go 的 net/http 包中r *http.Request 代表了客户端发来的 HTTP 请求对象。// 可以通过 r.Method 来获取这次请求使用的是什么方法Method例如GET、POST、PUT、DELETE 等。if r.Method http.MethodGet {fmt.Fprintf(w, 这是一个 GET 请求!!! )} else if r.Method http.MethodPost {fmt.Fprintf(w, 这是一个 POST 请求!!! )} else {fmt.Fprintf(w, 这是一个其他类型的请求%s!!! , r.Method)}for _, group : range e.routerGroups {routerName : SubStringLast(r.RequestURI, /group.name)if node : group.TreeNode.Get(routerName); node ! nil node.isEnd {// 路由匹配上了ctx : Context{W: w, R: r}// 先判断当前请求路由是否支持任意请求方式的Anyif handle, exist : group.handleFuncMap[node.routerName][ANY]; exist {group.methodHandle(handle, ctx)return}// 不支持 Any去该请求所对应的请求方式对应的 Map 里面去找是否有对应的路由if handle, exist : group.handleFuncMap[node.routerName][r.Method]; exist {group.methodHandle(handle, ctx)return}// 没找到对应的路由说明该请求方式不允许w.WriteHeader(http.StatusMethodNotAllowed)fmt.Fprintf(w, %s %s not allowed!!!\n, r.Method, r.RequestURI)return}}w.WriteHeader(http.StatusNotFound)fmt.Fprintf(w, %s %s not found!!!\n, r.Method, r.RequestURI)return }// 定义一个引擎结构体 type Engine struct {router }// 引擎结构体的初始化方法 func New() *Engine {return Engine{router: router{},} }// 引擎的启动方法 func (e *Engine) Run() {// for _, group : range e.routerGroups {// for name, value : range group.handleFuncMap {// http.HandleFunc(/group.namename, value)// }// }// 把 e 这个http处理器绑定到对应路由下http.Handle(/, e)err : http.ListenAndServe(:3986, nil)if err ! nil {log.Fatal(err)} }// main.gopackage mainimport (fmtnet/httpgithub.com/ErizJ/ZJGo/zjgo )func main() {fmt.Println(Hello World!)// // 注册 HTTP 路由 /hello// http.HandleFunc(/hello, func(w http.ResponseWriter, r *http.Request) {// fmt.Fprintf(w, Hello Go!)// })// // 启动 HTTP 服务器// err : http.ListenAndServe(8111, nil)// if err ! nil {// log.Fatal(err)// }engine : zjgo.New()g1 : engine.Group(user)g1.UseMiddleware(func(handleFunc zjgo.HandleFunc) zjgo.HandleFunc {return func(ctx *zjgo.Context) {fmt.Println(Pre Middleware ON!!!)handleFunc(ctx)fmt.Println(Post Middleware ON!!!)}})g1.Get(/hello, func(ctx *zjgo.Context) {fmt.Fprintf(ctx.W, http.MethodGet Hello Go!——user/hello)})// 浏览器地址栏输入的都是 GET 请求// 需要用 curl 或 Postman 来发一个真正的 POST 请求才会命中 Post handlerg1.Post(/info, func(ctx *zjgo.Context) {fmt.Println(HandleFunc ON!!!)fmt.Fprintf(ctx.W, http.MethodPost Hello Go!——user/info——POST)})g1.Get(/info, func(ctx *zjgo.Context) {fmt.Println(HandleFunc ON!!!)fmt.Fprintf(ctx.W, http.MethodGet Hello Go!——user/info——GET)})g1.Get(/get/:id, func(ctx *zjgo.Context) {fmt.Println(HandleFunc ON!!!)fmt.Fprintf(ctx.W, http.MethodGet Hello Go!——user/get/:id——GET)})g1.Get(/isEnd/get, func(ctx *zjgo.Context) {fmt.Println(HandleFunc ON!!!)fmt.Fprintf(ctx.W, http.MethodGet Hello Go!——user/isEnd/get——GET)})// 只要路由匹配就会执行对应的处理函数g1.Any(/any, func(ctx *zjgo.Context) {fmt.Fprintf(ctx.W, Hello Go!——user/any)})// g2 : engine.Group(order)// g2.Add(/hello, func(w http.ResponseWriter, r *http.Request) {// fmt.Fprintf(w, Hello Go!——order/hello)// })// g2.Add(/info, func(w http.ResponseWriter, r *http.Request) {// fmt.Fprintf(w, Hello Go!——order/info)// })fmt.Println(Starting...)engine.Run()}路由级别中间件 // zj.gopackage zjgoimport (fmtlognet/http )const ANY ANY// 定义处理响应函数 type HandleFunc func(ctx *Context)// 定义中间件 type MiddlewareFunc func(handleFunc HandleFunc) HandleFunc// 抽象出路由的概念 type routerGroup struct {name string // 组名handleFuncMap map[string]map[string]HandleFunc // 映射关系应该由每个路由组去维护handlerMethodMap map[string][]string // 记录GETPOST等请求方式所记录的路由实现对同一路由不同请求方式的支持middlewaresFuncMap map[string]map[string][]MiddlewareFunc // 定义路由级别中间件TreeNode *TreeNode // 记录该路由组下的路由前缀树middlewares []MiddlewareFunc // 定义通用中间件 }// 增加中间件 func (routerGroup *routerGroup) UseMiddleware(middlewareFunc ...MiddlewareFunc) { // 在Go语言中函数参数中的三个点...表示可变参数variadic parameter允许函数接受不定数量的同类型参数。routerGroup.middlewares append(routerGroup.middlewares, middlewareFunc...) }func (routerGroup *routerGroup) methodHandle(name string, method string, handle HandleFunc, ctx *Context) {// 执行组通用中间件任何路由组都可以执行该方法if routerGroup.middlewares ! nil {for _, middlewareFunc : range routerGroup.middlewares {handle middlewareFunc(handle) // 难以理解的话可以看作语句叠加}}// 路由级别组中间件if _, exist : routerGroup.middlewaresFuncMap[name][method]; exist {for _, middlewareFunc : range routerGroup.middlewaresFuncMap[name][method] {handle middlewareFunc(handle)}}handle(ctx) }// 定义路由结构体 type router struct {routerGroups []*routerGroup // 路由下面应该维护着不同的组 }// 添加路由组 func (r *router) Group(name string) *routerGroup {routerGroup : routerGroup{name: name,handleFuncMap: make(map[string]map[string]HandleFunc),handlerMethodMap: make(map[string][]string),middlewaresFuncMap: make(map[string]map[string][]MiddlewareFunc, 0),TreeNode: TreeNode{name: /, children: make([]*TreeNode, 0)},}r.routerGroups append(r.routerGroups, routerGroup)return routerGroup }// 给路由结构体添加一个添加路由功能的函数 // func (routerGroup *routerGroup) Add(name string, handleFunc HandleFunc) { // routerGroup.handleFuncMap[name] handleFunc // }// 由于 ANY POST GET 都需要重复相同的逻辑代码所以做一个提取操作 // 组册路由 func (routerGroup *routerGroup) registerRoute(name string, method string, handleFunc HandleFunc, middlewareFunc ...MiddlewareFunc) {if _, exist : routerGroup.handleFuncMap[name]; !exist {routerGroup.handleFuncMap[name] make(map[string]HandleFunc)routerGroup.middlewaresFuncMap[name] make(map[string][]MiddlewareFunc)}if _, exist : routerGroup.handleFuncMap[name][method]; !exist {routerGroup.handleFuncMap[name][method] handleFuncrouterGroup.handlerMethodMap[method] append(routerGroup.handlerMethodMap[method], name)routerGroup.middlewaresFuncMap[name][method] append(routerGroup.middlewaresFuncMap[name][method], middlewareFunc...)} else {panic(Under the same route, duplication is not allowed!!!)}routerGroup.TreeNode.Put(name) }// Any代表支持任意的请求方式 func (routerGroup *routerGroup) Any(name string, handleFunc HandleFunc, middlewareFunc ...MiddlewareFunc) {routerGroup.registerRoute(name, ANY, handleFunc, middlewareFunc...) }// POST代表支持POST请求方式 func (routerGroup *routerGroup) Post(name string, handleFunc HandleFunc, middlewareFunc ...MiddlewareFunc) {routerGroup.registerRoute(name, http.MethodPost, handleFunc, middlewareFunc...) }// GET代表支持GET请求方式 func (routerGroup *routerGroup) Get(name string, handleFunc HandleFunc, middlewareFunc ...MiddlewareFunc) {routerGroup.registerRoute(name, http.MethodGet, handleFunc, middlewareFunc...) }// DELETE代表支持DELETE请求方式 func (routerGroup *routerGroup) Delete(name string, handleFunc HandleFunc, middlewareFunc ...MiddlewareFunc) {routerGroup.registerRoute(name, http.MethodDelete, handleFunc, middlewareFunc...) }// PUT代表支持PUT请求方式 func (routerGroup *routerGroup) Put(name string, handleFunc HandleFunc, middlewareFunc ...MiddlewareFunc) {routerGroup.registerRoute(name, http.MethodPut, handleFunc, middlewareFunc...) }// PATCH代表支持PATCH请求方式 func (routerGroup *routerGroup) Patch(name string, handleFunc HandleFunc, middlewareFunc ...MiddlewareFunc) {routerGroup.registerRoute(name, http.MethodPatch, handleFunc, middlewareFunc...) }// 只要实现 ServeHTTP 这个方法就相当于实现了对应的 HTTP 处理器 // 结构体 Engine 实现了 ServeHTTP(w http.ResponseWriter, r *http.Request) 方法 // 所以它就自动实现了 http.Handler 接口因此可以直接被用于 http.ListenAndServe // Engine 实现了 ServeHTTP它就是一个合法的 http.Handler可以用 http.Handle 来绑定它到某个具体的路由路径上 func (e *Engine) ServeHTTP(w http.ResponseWriter, r *http.Request) {e.httpRequestHandle(w, r) }func (e *Engine) httpRequestHandle(w http.ResponseWriter, r *http.Request) {// 在 Go 的 net/http 包中r *http.Request 代表了客户端发来的 HTTP 请求对象。// 可以通过 r.Method 来获取这次请求使用的是什么方法Method例如GET、POST、PUT、DELETE 等。if r.Method http.MethodGet {fmt.Fprintf(w, 这是一个 GET 请求!!! )} else if r.Method http.MethodPost {fmt.Fprintf(w, 这是一个 POST 请求!!! )} else {fmt.Fprintf(w, 这是一个其他类型的请求%s!!! , r.Method)}for _, group : range e.routerGroups {routerName : SubStringLast(r.RequestURI, /group.name)if node : group.TreeNode.Get(routerName); node ! nil node.isEnd {// 路由匹配上了ctx : Context{W: w, R: r}// 先判断当前请求路由是否支持任意请求方式的Anyif handle, exist : group.handleFuncMap[node.routerName][ANY]; exist {group.methodHandle(node.routerName, ANY, handle, ctx)return}// 不支持 Any去该请求所对应的请求方式对应的 Map 里面去找是否有对应的路由if handle, exist : group.handleFuncMap[node.routerName][r.Method]; exist {group.methodHandle(node.routerName, r.Method, handle, ctx)return}// 没找到对应的路由说明该请求方式不允许w.WriteHeader(http.StatusMethodNotAllowed)fmt.Fprintf(w, %s %s not allowed!!!\n, r.Method, r.RequestURI)return}}w.WriteHeader(http.StatusNotFound)fmt.Fprintf(w, %s %s not found!!!\n, r.Method, r.RequestURI)return }// 定义一个引擎结构体 type Engine struct {router }// 引擎结构体的初始化方法 func New() *Engine {return Engine{router: router{},} }// 引擎的启动方法 func (e *Engine) Run() {// for _, group : range e.routerGroups {// for name, value : range group.handleFuncMap {// http.HandleFunc(/group.namename, value)// }// }// 把 e 这个http处理器绑定到对应路由下http.Handle(/, e)err : http.ListenAndServe(:3986, nil)if err ! nil {log.Fatal(err)} }// main.go package mainimport (fmtnet/httpgithub.com/ErizJ/ZJGo/zjgo )func Log(handleFunc zjgo.HandleFunc) zjgo.HandleFunc {return func(ctx *zjgo.Context) {fmt.Println([LOG] Middleware START)handleFunc(ctx)fmt.Println([LOG] Middleware END)} }func main() {fmt.Println(Hello World!)// // 注册 HTTP 路由 /hello// http.HandleFunc(/hello, func(w http.ResponseWriter, r *http.Request) {// fmt.Fprintf(w, Hello Go!)// })// // 启动 HTTP 服务器// err : http.ListenAndServe(8111, nil)// if err ! nil {// log.Fatal(err)// }engine : zjgo.New()g1 : engine.Group(user)g1.UseMiddleware(func(handleFunc zjgo.HandleFunc) zjgo.HandleFunc {return func(ctx *zjgo.Context) {fmt.Println(Pre Middleware ON!!!)handleFunc(ctx)fmt.Println(Post Middleware ON!!!)}})g1.Get(/hello, func(ctx *zjgo.Context) {fmt.Fprintf(ctx.W, http.MethodGet Hello Go!——user/hello)})// 浏览器地址栏输入的都是 GET 请求// 需要用 curl 或 Postman 来发一个真正的 POST 请求才会命中 Post handlerg1.Post(/info, func(ctx *zjgo.Context) {fmt.Println(HandleFunc ON!!!)fmt.Fprintf(ctx.W, http.MethodPost Hello Go!——user/info——POST)})g1.Get(/info, func(ctx *zjgo.Context) {fmt.Println(HandleFunc ON!!!)fmt.Fprintf(ctx.W, http.MethodGet Hello Go!——user/info——GET)}, Log)g1.Get(/get/:id, func(ctx *zjgo.Context) {fmt.Println(HandleFunc ON!!!)fmt.Fprintf(ctx.W, http.MethodGet Hello Go!——user/get/:id——GET)})g1.Get(/isEnd/get, func(ctx *zjgo.Context) {fmt.Println(HandleFunc ON!!!)fmt.Fprintf(ctx.W, http.MethodGet Hello Go!——user/isEnd/get——GET)})// 只要路由匹配就会执行对应的处理函数g1.Any(/any, func(ctx *zjgo.Context) {fmt.Fprintf(ctx.W, Hello Go!——user/any)})// g2 : engine.Group(order)// g2.Add(/hello, func(w http.ResponseWriter, r *http.Request) {// fmt.Fprintf(w, Hello Go!——order/hello)// })// g2.Add(/info, func(w http.ResponseWriter, r *http.Request) {// fmt.Fprintf(w, Hello Go!——order/info)// })fmt.Println(Starting...)engine.Run() }// 注意执行顺序理解包装这个词的意思把函数作为一个整体再往表面包装的这个概念 [LOG] Middleware START Pre Middleware ON!!! HandleFunc ON!!! Post Middleware ON!!! [LOG] Middleware END
http://www.zqtcl.cn/news/567282/

相关文章:

  • 奉贤网站建设专家高端自适应网站设计
  • 网站正在建设中 动态徐州网站建设方案咨询
  • 广东世纪达建设集团有限公司官方网站专业电商网站开发
  • 抚顺建设网站自适应网站建设推荐
  • 做网站的大公司手机页面
  • 网站建设的公司实习做什么系统设计
  • 兰州网站设计哪个平台好外贸网站定制公司哪家好
  • 做网站需要先买域名吗在线音乐网站开发数据库
  • 深圳优化网站搬家网站模板
  • 网站建设做的人多吗门户网站制作建设
  • 哪个网站可以做logo怀柔网页公司制作
  • 网站被抄袭怎么投诉网站建设丨金手指15
  • 中国交建平台seo搜索引擎优化是通过优化答案
  • 简述网站的建设流程图食品网站app建设方案
  • 西安建设厅网站首页听说上海又要封了
  • 兼职python做网站如何制作一个网站包含多个网页
  • 花园桥网站建设百度怎么创建网站
  • 做网站 客户一直要求改做网站学不需要做后台管理系统
  • 企业网站托管电话输入姓名查询个人征信
  • 域名注册了后怎么建设网站荆州市建设厅网站
  • 厦门网站建设合同wordpress的设置网址
  • 澎湃动力网站建设公司门户类网站建设需要多少钱
  • 祭祖网站怎么做咨询类网站开发的意义
  • 简书网站开发热门电影推荐
  • 中学教材数字化学习资源的建设——教材配套网站的设计及发展趋势建网站 发信息 做推广
  • 怎么写网站建设方案书制做网站的公司
  • 服务网站 建设原则游戏服务器租用多少钱一年
  • 软件网站下载现在出入深圳最新规定
  • 长宁专业网站制作公司陕西网站建设哪家专业
  • 重庆做的好的房产网站衡水的网站建设