1
0
mirror of https://github.com/astaxie/beego.git synced 2024-11-22 11:50:55 +00:00

add SaveToFile & docs

This commit is contained in:
astaxie 2013-04-16 18:20:55 +08:00
parent e865325556
commit 6ce02f1d1c
2 changed files with 347 additions and 261 deletions

View File

@ -6,10 +6,12 @@ import (
"encoding/xml" "encoding/xml"
"github.com/astaxie/beego/session" "github.com/astaxie/beego/session"
"html/template" "html/template"
"io"
"io/ioutil" "io/ioutil"
"mime/multipart" "mime/multipart"
"net/http" "net/http"
"net/url" "net/url"
"os"
"path" "path"
"strconv" "strconv"
"strings" "strings"
@ -197,6 +199,21 @@ func (c *Controller) GetFile(key string) (multipart.File, *multipart.FileHeader,
return c.Ctx.Request.FormFile(key) return c.Ctx.Request.FormFile(key)
} }
func (c *Controller) SaveToFile(fromfile, tofile string) error {
file, _, err := c.Ctx.Request.FormFile(fromfile)
if err != nil {
return err
}
defer file.Close()
f, err := os.OpenFile(tofile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
if err != nil {
return err
}
defer f.Close()
io.Copy(f, file)
return nil
}
func (c *Controller) StartSession() (sess session.SessionStore) { func (c *Controller) StartSession() (sess session.SessionStore) {
sess = GlobalSessions.SessionStart(c.Ctx.ResponseWriter, c.Ctx.Request) sess = GlobalSessions.SessionStart(c.Ctx.ResponseWriter, c.Ctx.Request)
return return

View File

@ -1,262 +1,331 @@
# 快速入门 # 快速入门
你对beego一无所知没关系这篇文档会很好的详细介绍beego的各个方面看这个文档之前首先确认你已经安装了beego如果你没有安装的话请看这篇[安装指南](Install.md) 你对beego一无所知没关系这篇文档会很好的详细介绍beego的各个方面看这个文档之前首先确认你已经安装了beego如果你没有安装的话请看这篇[安装指南](Install.md)
**导航** **导航**
- [最小应用](#-1) - [最小应用](#-1)
- [新建项目](#-2) - [新建项目](#-2)
- [开发模式](#-3) - [开发模式](#-3)
- [路由设置](#-4) - [路由设置](#-4)
- [静态文件](#-5) - [静态文件](#-5)
- [过滤和中间件](#-6) - [过滤和中间件](#-6)
- [模板处理](#-7) - [模板处理](#-7)
- [request处理](#-8) - [request处理](#-8)
- [跳转和错误](#-9) - [跳转和错误](#-9)
- [response处理](#-10) - [response处理](#-10)
- [Sessions](#-11) - [Sessions](#-11)
- [Cache设置](#-12) - [Cache设置](#-12)
- [安全的Map](#-13) - [安全的Map](#-13)
- [日志处理](#-14) - [日志处理](#-14)
- [第三方应用集成](#-15) - [第三方应用集成](#-15)
- [部署编译应用](#-16) - [部署编译应用](#-16)
## 最小应用 ## 最小应用
一个最小最简单的应用如下代码所示: 一个最小最简单的应用如下代码所示:
package main package main
import ( import (
"github.com/astaxie/beego" "github.com/astaxie/beego"
) )
type MainController struct { type MainController struct {
beego.Controller beego.Controller
} }
func (this *MainController) Get() { func (this *MainController) Get() {
this.Ctx.WriteString("hello world") this.Ctx.WriteString("hello world")
} }
func main() { func main() {
beego.Router("/", &MainController{}) beego.Router("/", &MainController{})
beego.Run() beego.Run()
} }
把上面的代码保存为hello.go然后通过命令行进行编译并执行 把上面的代码保存为hello.go然后通过命令行进行编译并执行
$ go build main.go $ go build main.go
$ ./hello $ ./hello
这个时候你可以打开你的浏览器,通过这个地址浏览[http://127.0.0.1:8080](http://127.0.0.1:8080)返回“hello world” 这个时候你可以打开你的浏览器,通过这个地址浏览[http://127.0.0.1:8080](http://127.0.0.1:8080)返回“hello world”
那么上面的代码到底做了些什么呢? 那么上面的代码到底做了些什么呢?
1、首先我们引入了包`github.com/astaxie/beego`,我们知道Go语言里面引入包会深度优先的去执行引入包的初始化(变量和init函数[更多](https://github.com/astaxie/build-web-application-with-golang/blob/master/ebook/02.3.md#maininit))beego包中会初始化一个BeeAPP的应用初始化一些参数。 1、首先我们引入了包`github.com/astaxie/beego`,我们知道Go语言里面引入包会深度优先的去执行引入包的初始化(变量和init函数[更多](https://github.com/astaxie/build-web-application-with-golang/blob/master/ebook/02.3.md#maininit))beego包中会初始化一个BeeAPP的应用初始化一些参数。
2、定义Controller这里我们定义了一个struct为`MainController`充分利用了Go语言的组合的概念匿名包含了`beego.Controller`,这样我们的`MainController`就拥有了`beego.Controller`的所有方法。 2、定义Controller这里我们定义了一个struct为`MainController`充分利用了Go语言的组合的概念匿名包含了`beego.Controller`,这样我们的`MainController`就拥有了`beego.Controller`的所有方法。
3、定义RESTFul方法通过匿名组合之后其实目前的`MainController`已经拥有了`Get`、`Post`、`Delete`、`Put`等方法这些方法是分别用来对应用户请求的Method函数如果用户发起的是`POST`请求,那么就执行`Post`函数。所以这里我们定义了`MainController`的`Get`方法用来重写继承的`Get`函数,这样当用户`GET`请求的时候就会执行该函数。 3、定义RESTFul方法通过匿名组合之后其实目前的`MainController`已经拥有了`Get`、`Post`、`Delete`、`Put`等方法这些方法是分别用来对应用户请求的Method函数如果用户发起的是`POST`请求,那么就执行`Post`函数。所以这里我们定义了`MainController`的`Get`方法用来重写继承的`Get`函数,这样当用户`GET`请求的时候就会执行该函数。
4、定义main函数所有的Go应用程序和C语言一样都是Main函数作为入口所以我们这里定义了我们应用的入口。 4、定义main函数所有的Go应用程序和C语言一样都是Main函数作为入口所以我们这里定义了我们应用的入口。
5、Router注册路由路由就是告诉beego当用户来请求的时候该如何去调用相应的Controller这里我们注册了请求`/`的时候,请求到`MainController`。这里我们需要知道Router函数的两个参数函数第一个是路径第二个是Controller的指针。 5、Router注册路由路由就是告诉beego当用户来请求的时候该如何去调用相应的Controller这里我们注册了请求`/`的时候,请求到`MainController`。这里我们需要知道Router函数的两个参数函数第一个是路径第二个是Controller的指针。
6、Run应用最后一步就是把在1中初始化的BeeApp开启起来其实就是内部监听了8080端口:`Go默认情况会监听你本机所有的IP上面的8080端口` 6、Run应用最后一步就是把在1中初始化的BeeApp开启起来其实就是内部监听了8080端口:`Go默认情况会监听你本机所有的IP上面的8080端口`
停止服务的话,请按`ctrl+c` 停止服务的话,请按`ctrl+c`
## 新建项目 ## 新建项目
通过如下命令创建beego项目首先进入gopath目录 通过如下命令创建beego项目首先进入gopath目录
bee create hello bee create hello
这样就建立了一个项目hello目录结构如下所示 这样就建立了一个项目hello目录结构如下所示
. .
├── conf ├── conf
│ └── app.conf │ └── app.conf
├── controllers ├── controllers
│ └── default.go │ └── default.go
├── main.go ├── main.go
├── models ├── models
├── static ├── static
│ ├── css │ ├── css
│ ├── img │ ├── img
│ └── js │ └── js
└── views └── views
└── index.tpl └── index.tpl
## 开发模式 ## 开发模式
通过bee创建的项目beego默认情况下是开发模式。 通过bee创建的项目beego默认情况下是开发模式。
我们可以通过如下的方式改变我们的模式: 我们可以通过如下的方式改变我们的模式:
beego.RunMode = "pro" beego.RunMode = "pro"
或者我们在conf/app.conf下面设置如下 或者我们在conf/app.conf下面设置如下
runmode = pro runmode = pro
以上两种效果一样。 以上两种效果一样。
开发模式中 开发模式中
- 开发模式下如果你的目录不存在views目录那么会出现类似下面的错误提示 - 开发模式下如果你的目录不存在views目录那么会出现类似下面的错误提示
2013/04/13 19:36:17 [W] [stat views: no such file or directory] 2013/04/13 19:36:17 [W] [stat views: no such file or directory]
- 模板会自动重新加载不缓存。 - 模板会自动重新加载不缓存。
- 如果服务端出错,那么就会在浏览器端显示如下类似的截图: - 如果服务端出错,那么就会在浏览器端显示如下类似的截图:
![](images/dev.png) ![](images/dev.png)
## 路由设置 ## 路由设置
路由的主要功能是实现从请求地址到实现方法beego中封装了`Controller`,所以路由是从路径到`ControllerInterface`的过程,`ControllerInterface`的方法有如下: 路由的主要功能是实现从请求地址到实现方法beego中封装了`Controller`,所以路由是从路径到`ControllerInterface`的过程,`ControllerInterface`的方法有如下:
type ControllerInterface interface { type ControllerInterface interface {
Init(ct *Context, cn string) Init(ct *Context, cn string)
Prepare() Prepare()
Get() Get()
Post() Post()
Delete() Delete()
Put() Put()
Head() Head()
Patch() Patch()
Options() Options()
Finish() Finish()
Render() error Render() error
} }
这些方法`beego.Controller`都已经实现了所以只要用户定义struct的时候匿名包含就可以了。当然更灵活的方法就是用户可以去自定义类似的方法然后实现自己的逻辑。 这些方法`beego.Controller`都已经实现了所以只要用户定义struct的时候匿名包含就可以了。当然更灵活的方法就是用户可以去自定义类似的方法然后实现自己的逻辑。
用户可以通过如下的方式进行路由设置: 用户可以通过如下的方式进行路由设置:
beego.Router("/", &controllers.MainController{}) beego.Router("/", &controllers.MainController{})
beego.Router("/admin", &admin.UserController{}) beego.Router("/admin", &admin.UserController{})
beego.Router("/admin/index", &admin.ArticleController{}) beego.Router("/admin/index", &admin.ArticleController{})
beego.Router("/admin/addpkg", &admin.AddController{}) beego.Router("/admin/addpkg", &admin.AddController{})
为了用户更加方便的路由设置beego参考了sinatra的路由实现支持多种方式的路由 为了用户更加方便的路由设置beego参考了sinatra的路由实现支持多种方式的路由
- beego.Router("/api/:id([0-9]+)", &controllers.RController{}) - beego.Router("/api/:id([0-9]+)", &controllers.RController{})
自定义正则匹配 //匹配 /api/123 :id= 123 自定义正则匹配 //匹配 /api/123 :id= 123
- beego.Router("/news/:all", &controllers.RController{}) - beego.Router("/news/:all", &controllers.RController{})
全匹配方式 //匹配 /news/path/to/123.html :all= path/to/123.html 全匹配方式 //匹配 /news/path/to/123.html :all= path/to/123.html
- beego.Router("/user/:username([\w]+)", &controllers.RController{}) - beego.Router("/user/:username([\w]+)", &controllers.RController{})
正则字符串匹配 //匹配 /user/astaxie :username = astaxie 正则字符串匹配 //匹配 /user/astaxie :username = astaxie
- beego.Router("/download/*.*", &controllers.RController{}) - beego.Router("/download/*.*", &controllers.RController{})
*匹配方式 //匹配 /download/file/api.xml :path= file/api :ext=xml *匹配方式 //匹配 /download/file/api.xml :path= file/api :ext=xml
- beego.Router("/download/ceshi/*", &controllers.RController{}) - beego.Router("/download/ceshi/*", &controllers.RController{})
*全匹配方式 //匹配 /download/ceshi/file/api.json :splat=file/api.json *全匹配方式 //匹配 /download/ceshi/file/api.json :splat=file/api.json
- beego.Router("/:id:int", &controllers.RController{}) - beego.Router("/:id:int", &controllers.RController{})
int类型设置方式 //匹配 :id为int类型框架帮你实现了正则([0-9]+) int类型设置方式 //匹配 :id为int类型框架帮你实现了正则([0-9]+)
- beego.Router("/:hi:string", &controllers.RController{}) - beego.Router("/:hi:string", &controllers.RController{})
string类型设置方式 //匹配 :hi为string类型。框架帮你实现了正则([\w]+) string类型设置方式 //匹配 :hi为string类型。框架帮你实现了正则([\w]+)
## 静态文件 ## 静态文件
Go语言内部其实已经提供了`http.ServeFile`通过这个函数可以实现静态文件的服务。beego针对这个功能进行了一层封装通过下面的方式进行静态文件注册 Go语言内部其实已经提供了`http.ServeFile`通过这个函数可以实现静态文件的服务。beego针对这个功能进行了一层封装通过下面的方式进行静态文件注册
beego.SetStaticPath("/static","public") beego.SetStaticPath("/static","public")
- 第一个参数是路径url路径信息 - 第一个参数是路径url路径信息
- 第二个参数是静态文件目录(相对应用所在的目录) - 第二个参数是静态文件目录(相对应用所在的目录)
beego支持多个目录的静态文件注册用户可以注册如下的静态文件目录 beego支持多个目录的静态文件注册用户可以注册如下的静态文件目录
beego.SetStaticPath("/images","images") beego.SetStaticPath("/images","images")
beego.SetStaticPath("/css","css") beego.SetStaticPath("/css","css")
beego.SetStaticPath("/js","js") beego.SetStaticPath("/js","js")
设置了如上的静态目录之后,用户访问`/images/login/login.png`,那么就会访问应用对应的目录下面的`images/login/login.png`文件。如果是访问`/static/img/logo.png`,那么就访问`public/img/logo.png`文件。 设置了如上的静态目录之后,用户访问`/images/login/login.png`,那么就会访问应用对应的目录下面的`images/login/login.png`文件。如果是访问`/static/img/logo.png`,那么就访问`public/img/logo.png`文件。
## 过滤和中间件 ## 过滤和中间件
beego支持自定义过滤中间件例如安全验证强制跳转等 beego支持自定义过滤中间件例如安全验证强制跳转等
如下例子所示验证用户名是否是admin应用于全部的请求 如下例子所示验证用户名是否是admin应用于全部的请求
var FilterUser = func(w http.ResponseWriter, r *http.Request) { var FilterUser = func(w http.ResponseWriter, r *http.Request) {
if r.URL.User == nil || r.URL.User.Username() != "admin" { if r.URL.User == nil || r.URL.User.Username() != "admin" {
http.Error(w, "", http.StatusUnauthorized) http.Error(w, "", http.StatusUnauthorized)
} }
} }
beego.Filter(FilterUser) beego.Filter(FilterUser)
还可以通过参数进行过滤,如果匹配参数就执行 还可以通过参数进行过滤,如果匹配参数就执行
beego.Router("/:id([0-9]+)", &admin.EditController{}) beego.Router("/:id([0-9]+)", &admin.EditController{})
beego.FilterParam("id", func(rw http.ResponseWriter, r *http.Request) { beego.FilterParam("id", func(rw http.ResponseWriter, r *http.Request) {
dosomething() dosomething()
}) })
当然你还可以通过前缀过滤 当然你还可以通过前缀过滤
beego.FilterPrefixPath("/admin", func(rw http.ResponseWriter, r *http.Request) { beego.FilterPrefixPath("/admin", func(rw http.ResponseWriter, r *http.Request) {
dosomething() dosomething()
}) })
## 模板处理 ## 模板处理
### 模板目录 ### 模板目录
beego中默认的模板目录是`views`用户可以把你的模板文件放到该目录下beego会自动在该目录下的所有模板文件进行解析并缓存开发模式下会每次重新解析不做缓存。当然用户可以通过如下的方式改变模板的目录 beego中默认的模板目录是`views`用户可以把你的模板文件放到该目录下beego会自动在该目录下的所有模板文件进行解析并缓存开发模式下会每次重新解析不做缓存。当然用户可以通过如下的方式改变模板的目录
beego.ViewsPath = "/myviewpath" beego.ViewsPath = "/myviewpath"
### 自动渲染 ### 自动渲染
beego中用户无需手动的调用渲染输出模板beego会自动的在调用玩相应的method方法之后调用Render函数当然如果你的应用是不需要模板输出的那么你可以在配置文件或者在main.go中设置关闭自动渲染。 beego中用户无需手动的调用渲染输出模板beego会自动的在调用玩相应的method方法之后调用Render函数当然如果你的应用是不需要模板输出的那么你可以在配置文件或者在main.go中设置关闭自动渲染。
配置文件配置如下: 配置文件配置如下:
autorender = false autorender = false
main.go文件中设置如下 main.go文件中设置如下
beego.AutoRender = false beego.AutoRender = false
### 模板名称 ### 模板名称
beego采用了Go语言内置的模板引擎所有模板的语法和Go的一模一样至于如何写模板文件详细的请参考[模板教程](https://github.com/astaxie/build-web-application-with-golang/blob/master/ebook/07.4.md)。 beego采用了Go语言内置的模板引擎所有模板的语法和Go的一模一样至于如何写模板文件详细的请参考[模板教程](https://github.com/astaxie/build-web-application-with-golang/blob/master/ebook/07.4.md)。
用户通过在Controller的对应方法中设置相应的模板名称beego会自动的在viewpath目录下查询该文件并渲染例如下面的设置beego会在admin下面找add.tpl文件进行渲染 用户通过在Controller的对应方法中设置相应的模板名称beego会自动的在viewpath目录下查询该文件并渲染例如下面的设置beego会在admin下面找add.tpl文件进行渲染
this.TplNames = "admin/add.tpl" this.TplNames = "admin/add.tpl"
我们看到上面的模板后缀名是tplbeego默认情况下支持tpl和html后缀名的模板文件如果你的后缀名不是这两种请进行如下设置 我们看到上面的模板后缀名是tplbeego默认情况下支持tpl和html后缀名的模板文件如果你的后缀名不是这两种请进行如下设置
beego.AddTemplateExt("你文件的后缀名") beego.AddTemplateExt("你文件的后缀名")
当你设置了自动渲染然后在你的Controller中没有设置任何的TplNames那么beego会自动设置你的模板文件如下 当你设置了自动渲染然后在你的Controller中没有设置任何的TplNames那么beego会自动设置你的模板文件如下
c.TplNames = c.ChildName + "/" + c.Ctx.Request.Method + "." + c.TplExt c.TplNames = c.ChildName + "/" + c.Ctx.Request.Method + "." + c.TplExt
也就是你对应的Controller名字+请求方法名.模板后缀也就是如果你的Controller名是`AddController`,请求方法是`POST`,默认的文件后缀是`tpl`,那么就会默认请求`/viewpath/AddController/POST.tpl`文件。 也就是你对应的Controller名字+请求方法名.模板后缀也就是如果你的Controller名是`AddController`,请求方法是`POST`,默认的文件后缀是`tpl`,那么就会默认请求`/viewpath/AddController/POST.tpl`文件。
### lauout设计 ### lauout设计
beego支持layout设计例如你在管理系统中其实整个的管理界面是固定的支会变化中间的部分那么你可以通过如下的设置
### 模板函数
this.Layout = "admin/layout.html"
## request处理 this.TplNames = "admin/add.tpl"
## 跳转和错误 在layout.html中你必须设置如下的变量
## response处理 {{.LayoutContent}}
## Sessions beego就会首先解析TplNames指定的文件获取内容赋值给LayoutContent然后最后渲染layout.html文件。
## Cache设置 目前采用首先把目录下所有的文件进行缓存所以用户还可以通过类似这样的方式实现layout
## 安全的Map {{template "header.html"}}
处理逻辑
## 日志处理 {{template "footer.html"}}
## 第三方应用集成 ### 模板函数
beego支持用户定义模板函数但是必须在`beego.Run()`调用之前,设置如下:
## 部署编译应用
func hello(in string)(out string){
- [beego介绍](README.md) out = in + "world"
return
}
beego.AddFuncMap("hi",hello)
定义之后你就可以在模板中这样使用了:
{{.Content | hi}}
目前beego内置的模板函数有如下
* markdown
实现了把markdown文本转化为html信息使用方法{{markdown .Content}}
* dateformat
实现了时间的格式化,返回字符串,使用方法{{dateformat .Time "2006-01-02T15:04:05Z07:00"}}
* date
实现了类似PHP的date函数可以很方便的根据字符串返回时间使用方法{{date .T "Y-m-d H:i:s"}}
* compare
实现了比较两个对象的比较如果相同返回true否者false使用方法{{compare .A .B}}
* substr
实现了字符串的截取,支持中文截取的完美截取,使用方法{{substr .Str 0 30}}
* html2str
实现了把html转化为字符串剔除一些script、css之类的元素返回纯文本信息使用方法{{html2str .Htmlinfo}}
* str2html
实现了把相应的字符串当作HTML来输出不转义使用方法{{str2html .Strhtml}}
* htmlquote
实现了基本的html字符转义使用方法{{htmlquote .quote}}
* htmlunquote
实现了基本的反转移字符,使用方法{{htmlunquote .unquote}}
## request处理
我们经常需要获取用户传递的数据包括Get、POST等方式的请求beego里面会自动解析这些数据你可以通过如下方式获取数据
- GetString
- GetInt
- GetBool
### 文件上传
- GetFile
- SaveToFile
## 跳转和错误
## response处理
## Sessions
## Cache设置
## 安全的Map
## 日志处理
## 第三方应用集成
## 部署编译应用
- [beego介绍](README.md)
- [一步一步开发应用](Tutorial.md) - [一步一步开发应用](Tutorial.md)