一个简单 Go Web MVC 框架实现思路
需要的知识点
为了防止你的心里不适,需要以下知识点:
- Go 基本知识
- Go 反射的深入理解
- 使用过框架
Go Web 服务器搭建
package main import (
"fmt"
"net/http"
) func do(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello World!") //这个写入到w的是输出到客户端的
} func main() {
http.HandleFunc("/", do) //设置访问的路由
http.ListenAndServe(":9090", nil) //设置监听的端口
}
上面的例子调用了http默认的DefaultServeMux来添加路由,需要提供两个参数,第一个参数是希望用户访问此资源的URL路径(保存在r.URL.Path),第二参数是即将要执行的函数,以提供用户访问的资源。
Go默认的路由添加是通过函数http.Handle和http.HandleFunc等来添加,底层都是调用了DefaultServeMux.Handle(pattern string, handler Handler),这个函数会把路由信息存储在一个map信息中map[string]muxEntry。
Go监听端口,然后接收到tcp连接会扔给Handler来处理,上面的例子默认nil即为http.DefaultServeMux,通过DefaultServeMux.ServeHTTP函数来进行调度,遍历之前存储的map路由信息,和用户访问的URL进行匹配,以查询对应注册的处理函数。
你可以通过文档查看 http.ListenAndServe 的方法,第二个参数是 Handler 类型的接口,只要实现 Handler 接口,就可以实现自定义路由。
func ListenAndServe(addr string, handler Handler) error
实现自定义路由:
package main import (
"fmt"
"net/http"
) type MyMux struct {
} func (p *MyMux) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if r.URL.Path == "/" {
sayhelloName(w, r)
return
}
http.NotFound(w, r)
return
} func sayhelloName(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello myroute!")
} func main() {
mux := &MyMux{}
http.ListenAndServe(":9090", mux)
}
通过自定义路由,实现简单 MVC 框架
两个基本结构的定义:
type controllerInfo struct {
url string
controllerType reflect.Type
}
type ControllerRegistor struct {
routers []*controllerInfo
}
整体思路:
- controllerInfo url 是添加时候对应的路由, controllerType 反射类型。
- 通过 mux.Add("/", &DefaultController{}) 前台添加的信息,放到一个 routers []*controllerInfo 数组中
- 每一次请求都会遍历 routes, 判断当前的 r.URL.Path 是否与 routes 里面一个相等,如果相等, 通过类型反射,执行相应的方法。
流程图:

源码实现
package main import (
"fmt"
"net/http"
"reflect"
) type controllerInfo struct {
url string
controllerType reflect.Type
} type ControllerRegistor struct {
routers []*controllerInfo
} type ControllerInterface interface {
Do()
} type UserController struct { } type DefaultController struct { } func (u *UserController) Do() {
fmt.Println("I`m UserController")
} func (d *DefaultController) Do() {
fmt.Println("I`m DefaultController")
} func (p *ControllerRegistor) Add(pattern string, c ControllerInterface) { //now create the Route
t := reflect.TypeOf(c).Elem()
route := &controllerInfo{}
route.url = pattern
route.controllerType = t
p.routers = append(p.routers, route) } // AutoRoute
func (p *ControllerRegistor) ServeHTTP(w http.ResponseWriter, r *http.Request) { var started bool
requestPath := r.URL.Path fmt.Println(requestPath) //find a matching Route
for _, route := range p.routers { if requestPath == route.url {
vc := reflect.New(route.controllerType)
method := vc.MethodByName("Do")
method.Call(nil)
started = true
fmt.Fprintf(w, "Hello " + route.controllerType.Name())
break
}
} //if no matches to url, throw a not found exception
if started == false {
http.NotFound(w, r)
}
} func main() {
mux := &ControllerRegistor{} mux.Add("/", &DefaultController{})
mux.Add("/user", &UserController{}) s := &http.Server{
Addr: ":9527",
Handler: mux,
} s.ListenAndServe()
}
以上只是一个简陋的实现思路,可以优化加上具体的功能和通过参数调用方法等。
参考链接:
一个简单 Go Web MVC 框架实现思路的更多相关文章
- Node.js简单介绍并实现一个简单的Web MVC框架
编号:1018时间:2016年6月13日16:06:41功能:Node.js简单介绍并实现一个简单的Web MVC框架URL :https://cnodejs.org/topic/4f16442cca ...
- 用Python写一个简单的Web框架
一.概述 二.从demo_app开始 三.WSGI中的application 四.区分URL 五.重构 1.正则匹配URL 2.DRY 3.抽象出框架 六.参考 一.概述 在Python中,WSGI( ...
- 一个简单的web框架实现
一个简单的web框架实现 #!/usr/bin/env python # -- coding: utf-8 -- __author__ = 'EchoRep' from wsgiref.simple_ ...
- 动手写一个简单的Web框架(模板渲染)
动手写一个简单的Web框架(模板渲染) 在百度上搜索jinja2,显示的大部分内容都是jinja2的渲染语法,这个不是Web框架需要做的事,最终,居然在Werkzeug的官方文档里找到模板渲染的代码. ...
- 动手写一个简单的Web框架(Werkzeug路由问题)
动手写一个简单的Web框架(Werkzeug路由问题) 继承上一篇博客,实现了HelloWorld,但是这并不是一个Web框架,只是自己手写的一个程序,别人是无法通过自己定义路由和返回文本,来使用的, ...
- 动手写一个简单的Web框架(HelloWorld的实现)
动手写一个简单的Web框架(HelloWorld的实现) 关于python的wsgi问题可以看这篇博客 我就不具体阐述了,简单来说,wsgi标准需要我们提供一个可以被调用的python程序,可以实函数 ...
- CodeIgniter框架——创建一个简单的Web站点(include MySQL基本操作)
目标 使用 CodeIgniter 创建一个简单的 Web 站点.该站点将有一个主页,显示一些宣传文本和一个表单,该表单将发布到数据库表中. 按照 CodeIgniter 的术语,可将这些需求转换为以 ...
- Spring 4 官方文档学习(十一)Web MVC 框架之配置Spring MVC
内容列表: 启用MVC Java config 或 MVC XML namespace 修改已提供的配置 类型转换和格式化 校验 拦截器 内容协商 View Controllers View Reso ...
- struts1:(Struts重构)构建一个简单的基于MVC模式的JavaWeb
在构建一个简单的基于MVC模式的JavaWeb 中,我们使用了JSP+Servlet+JavaBean构建了一个基于MVC模式的简单登录系统,但在其小结中已经指出,这种模式下的Controller 和 ...
随机推荐
- 常用类一一字符串相关类一一StringBuilder,StringBuffer。
package cn.bjsxt.stringbuilder; /** * String 不可变字符序列 * StringBuilder StringBuffer都是是可变字符序列 * 区别在于Str ...
- 重学Java
Java web 的课程告一段落了 现在我觉得我应该重新学习一下 Java基础 先分享下昨天学习递归后写的两个短短的代码 1.求5的阶乘 package test; public class fiv ...
- 软件工程导论复习 如何画系统流程图和数据流图 part2
数据流图(DFD) 数据流图,简称DFD,是SA方法中用于表示系统逻辑模型的一种工具,它以图形的方式描绘数据在系统中流动和处理的过程,由于它只反映系统必须完成的逻辑功能,所以它是一种功能模型.下 ...
- 静态网页开发技术-HTML
今天我重新复习了一下静态网页开发技术,概括如下. 一 .HTML文档结构与基本语法 :放置了标签的文本文档,可供浏览器解释执行的网页文件 1.注释标记 2.标记 3.属性 二.基本标记与使用 1.网页 ...
- js中函数的使用方式及回调函数
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- JDK中rt.jar、tools.jar和dt.jar作用
dt.jar和tools.jar位于:{Java_Home}/lib/下,而rt.jar位于:{Java_Home}/jre/lib/下,其中: rt.jar是JAVA基础类库,也就是你在java d ...
- crsf 跨站请求伪造
[crsf 跨站请求伪造] CSRF(Cross-site request forgery),中文名称:跨站请求伪造.核心为利用浏览器帮助提交cookie.采用随机数方可防御.估计大部小站均无CSRF ...
- easyUIDataGrid分页
package com.cn.eport.util; import java.util.List; /** * * * @author zh * */ public class DataGrid im ...
- Java GC的原理
Java GC(garbage collec,垃圾收集,回收) GC是对JVM中的内存进行标记和回收,Sun公司的JDK用的虚拟机都是HotSpot 对象化的实例是放在heap堆内存中的,这里讲的分代 ...
- 神经网络出现nan原因?以及解决
之前在TensorFlow中实现不同的神经网络,作为新手,发现经常会出现计算的loss中,出现Nan值的情况,总的来说,TensorFlow中出现Nan值的情况有两种,一种是在loss中计算后得到了N ...