@@ -10,140 +10,140 @@ MVC设计模式是目前Web应用开发中最常见的架构模式,通过分
10
10
前面小节介绍了路由实现了注册struct的功能,而struct中实现了REST方式,因此我们需要设计一个用于逻辑处理controller的基类,这里主要设计了两个类型,一个struct、一个interface
11
11
``` Go
12
12
13
- type Controller struct {
14
- Ct *Context
15
- Tpl *template.Template
16
- Data map [interface {}]interface {}
17
- ChildName string
18
- TplNames string
19
- Layout []string
20
- TplExt string
21
- }
22
-
23
- type ControllerInterface interface {
24
- Init (ct *Context, cn string ) // 初始化上下文和子类名称
25
- Prepare () // 开始执行之前的一些处理
26
- Get () // method=GET的处理
27
- Post () // method=POST的处理
28
- Delete () // method=DELETE的处理
29
- Put () // method=PUT的处理
30
- Head () // method=HEAD的处理
31
- Patch () // method=PATCH的处理
32
- Options () // method=OPTIONS的处理
33
- Finish () // 执行完成之后的处理
34
- Render () error // 执行完method对应的方法之后渲染页面
35
- }
13
+ type Controller struct {
14
+ Ct *Context
15
+ Tpl *template.Template
16
+ Data map [interface {}]interface {}
17
+ ChildName string
18
+ TplNames string
19
+ Layout []string
20
+ TplExt string
21
+ }
22
+
23
+ type ControllerInterface interface {
24
+ Init (ct *Context, cn string ) // 初始化上下文和子类名称
25
+ Prepare () // 开始执行之前的一些处理
26
+ Get () // method=GET的处理
27
+ Post () // method=POST的处理
28
+ Delete () // method=DELETE的处理
29
+ Put () // method=PUT的处理
30
+ Head () // method=HEAD的处理
31
+ Patch () // method=PATCH的处理
32
+ Options () // method=OPTIONS的处理
33
+ Finish () // 执行完成之后的处理
34
+ Render () error // 执行完method对应的方法之后渲染页面
35
+ }
36
36
```
37
37
那么前面介绍的路由add函数的时候是定义了ControllerInterface类型,因此,只要我们实现这个接口就可以,所以我们的基类Controller实现如下的方法:
38
38
``` Go
39
39
40
- func (c *Controller ) Init (ct *Context, cn string) {
41
- c.Data = make (map [interface {}]interface {})
42
- c.Layout = make ([]string , 0 )
43
- c.TplNames = " "
44
- c.ChildName = cn
45
- c.Ct = ct
46
- c.TplExt = " tpl"
47
- }
40
+ func (c *Controller ) Init (ct *Context , cn string ) {
41
+ c.Data = make (map [interface {}]interface {})
42
+ c.Layout = make ([]string , 0 )
43
+ c.TplNames = " "
44
+ c.ChildName = cn
45
+ c.Ct = ct
46
+ c.TplExt = " tpl"
47
+ }
48
48
49
- func (c *Controller ) Prepare () {
49
+ func (c *Controller ) Prepare () {
50
50
51
- }
51
+ }
52
52
53
- func (c *Controller ) Finish () {
53
+ func (c *Controller ) Finish () {
54
54
55
- }
55
+ }
56
56
57
- func (c *Controller ) Get () {
58
- http.Error (c.Ct .ResponseWriter , " Method Not Allowed" , 405 )
59
- }
57
+ func (c *Controller ) Get () {
58
+ http.Error (c.Ct .ResponseWriter , " Method Not Allowed" , 405 )
59
+ }
60
60
61
- func (c *Controller ) Post () {
62
- http.Error (c.Ct .ResponseWriter , " Method Not Allowed" , 405 )
63
- }
61
+ func (c *Controller ) Post () {
62
+ http.Error (c.Ct .ResponseWriter , " Method Not Allowed" , 405 )
63
+ }
64
64
65
- func (c *Controller ) Delete () {
66
- http.Error (c.Ct .ResponseWriter , " Method Not Allowed" , 405 )
67
- }
65
+ func (c *Controller ) Delete () {
66
+ http.Error (c.Ct .ResponseWriter , " Method Not Allowed" , 405 )
67
+ }
68
68
69
- func (c *Controller ) Put () {
70
- http.Error (c.Ct .ResponseWriter , " Method Not Allowed" , 405 )
71
- }
69
+ func (c *Controller ) Put () {
70
+ http.Error (c.Ct .ResponseWriter , " Method Not Allowed" , 405 )
71
+ }
72
72
73
- func (c *Controller ) Head () {
74
- http.Error (c.Ct .ResponseWriter , " Method Not Allowed" , 405 )
75
- }
73
+ func (c *Controller ) Head () {
74
+ http.Error (c.Ct .ResponseWriter , " Method Not Allowed" , 405 )
75
+ }
76
76
77
- func (c *Controller ) Patch () {
78
- http.Error (c.Ct .ResponseWriter , " Method Not Allowed" , 405 )
79
- }
77
+ func (c *Controller ) Patch () {
78
+ http.Error (c.Ct .ResponseWriter , " Method Not Allowed" , 405 )
79
+ }
80
80
81
- func (c *Controller ) Options () {
82
- http.Error (c.Ct .ResponseWriter , " Method Not Allowed" , 405 )
83
- }
81
+ func (c *Controller ) Options () {
82
+ http.Error (c.Ct .ResponseWriter , " Method Not Allowed" , 405 )
83
+ }
84
84
85
- func (c *Controller ) Render () error {
86
- if len (c.Layout ) > 0 {
87
- var filenames []string
88
- for _ , file := range c.Layout {
89
- filenames = append (filenames, path.Join (ViewsPath, file))
90
- }
91
- t , err := template.ParseFiles (filenames...)
92
- if err != nil {
93
- Trace (" template ParseFiles err:" , err)
94
- }
95
- err = t.ExecuteTemplate (c.Ct .ResponseWriter , c.TplNames , c.Data )
96
- if err != nil {
97
- Trace (" template Execute err:" , err)
98
- }
99
- } else {
100
- if c.TplNames == " " {
101
- c.TplNames = c.ChildName + " /" + c.Ct .Request .Method + " ." + c.TplExt
102
- }
103
- t , err := template.ParseFiles (path.Join (ViewsPath, c.TplNames ))
104
- if err != nil {
105
- Trace (" template ParseFiles err:" , err)
106
- }
107
- err = t.Execute (c.Ct .ResponseWriter , c.Data )
108
- if err != nil {
109
- Trace (" template Execute err:" , err)
110
- }
85
+ func (c *Controller ) Render () error {
86
+ if len (c.Layout ) > 0 {
87
+ var filenames []string
88
+ for _ , file := range c.Layout {
89
+ filenames = append (filenames, path.Join (ViewsPath, file))
90
+ }
91
+ t , err := template.ParseFiles (filenames...)
92
+ if err != nil {
93
+ Trace (" template ParseFiles err:" , err)
94
+ }
95
+ err = t.ExecuteTemplate (c.Ct .ResponseWriter , c.TplNames , c.Data )
96
+ if err != nil {
97
+ Trace (" template Execute err:" , err)
98
+ }
99
+ } else {
100
+ if c.TplNames == " " {
101
+ c.TplNames = c.ChildName + " /" + c.Ct .Request .Method + " ." + c.TplExt
102
+ }
103
+ t , err := template.ParseFiles (path.Join (ViewsPath, c.TplNames ))
104
+ if err != nil {
105
+ Trace (" template ParseFiles err:" , err)
106
+ }
107
+ err = t.Execute (c.Ct .ResponseWriter , c.Data )
108
+ if err != nil {
109
+ Trace (" template Execute err:" , err)
111
110
}
112
- return nil
113
111
}
112
+ return nil
113
+ }
114
114
115
- func (c *Controller ) Redirect (url string, code int) {
116
- c.Ct .Redirect (code, url)
117
- }
115
+ func (c *Controller ) Redirect (url string , code int ) {
116
+ c.Ct .Redirect (code, url)
117
+ }
118
118
```
119
119
上面的controller基类已经实现了接口定义的函数,通过路由根据url执行相应的controller的原则,会依次执行如下:
120
120
``` Go
121
121
122
- Init () 初始化
123
- Prepare () 执行之前的初始化,每个继承的子类可以来实现该函数
124
- method () 根据不同的method执行不同的函数:GET、POST、PUT、HEAD等,子类来实现这些函数,如果没实现,那么默认都是403
125
- Render () 可选,根据全局变量AutoRender来判断是否执行
126
- Finish () 执行完之后执行的操作,每个继承的子类可以来实现该函数
122
+ Init () 初始化
123
+ Prepare () 执行之前的初始化,每个继承的子类可以来实现该函数
124
+ method () 根据不同的method执行不同的函数:GET、POST、PUT、HEAD等,子类来实现这些函数,如果没实现,那么默认都是403
125
+ Render () 可选,根据全局变量AutoRender来判断是否执行
126
+ Finish () 执行完之后执行的操作,每个继承的子类可以来实现该函数
127
127
```
128
128
## 应用指南
129
129
上面beego框架中完成了controller基类的设计,那么我们在我们的应用中可以这样来设计我们的方法:
130
130
``` Go
131
131
132
- package controllers
132
+ package controllers
133
133
134
- import (
135
- " github.com/astaxie/beego"
136
- )
134
+ import (
135
+ " github.com/astaxie/beego"
136
+ )
137
137
138
- type MainController struct {
139
- beego.Controller
140
- }
138
+ type MainController struct {
139
+ beego.Controller
140
+ }
141
141
142
- func (this *MainController ) Get () {
143
- this.Data [" Username" ] = " astaxie"
144
- this.Data [" Email" ] = " astaxie@gmail.com"
145
- this.TplNames = " index.tpl"
146
- }
142
+ func (this *MainController ) Get () {
143
+ this.Data [" Username" ] = " astaxie"
144
+ this.Data [" Email" ] = " astaxie@gmail.com"
145
+ this.TplNames = " index.tpl"
146
+ }
147
147
```
148
148
上面的方式我们实现了子类MainController,实现了Get方法,那么如果用户通过其他的方式(POST/HEAD等)来访问该资源都将返回403,而如果是Get来访问,因为我们设置了AutoRender=true,那么在执行完Get方法之后会自动执行Render函数,就会显示如下界面:
149
149
@@ -152,16 +152,16 @@ MVC设计模式是目前Web应用开发中最常见的架构模式,通过分
152
152
index.tpl的代码如下所示,我们可以看到数据的设置和显示都是相当的简单方便:
153
153
``` html
154
154
155
- <!DOCTYPE html>
156
- <html >
157
- <head >
158
- <title >beego welcome template</title >
159
- </head >
160
- <body >
161
- <h1 >Hello, world!{{.Username}},{{.Email}}</h1 >
162
- </body >
163
- </html >
164
-
155
+ <!DOCTYPE html>
156
+ <html >
157
+ <head >
158
+ <title >beego welcome template</title >
159
+ </head >
160
+ <body >
161
+ <h1 >Hello, world!{{.Username}},{{.Email}}</h1 >
162
+ </body >
163
+ </html >
164
+
165
165
```
166
166
167
167
## links
0 commit comments