1.bee#
在安装之前,我们做一些准备工作
bee是beego的一个工具,我们在Linux下安装使用
我们创建一个目录作为即将使用的目录
[root@linuxea.com ~]# mkdir /home/mark -p
初始化目录
[root@linuxea.com /home/mark]# go mod init mark
另外,我们需要配置GOPATH环境变量
[root@linuxea.com /home/mark]# export GOPATH=/home/mark
1.1开始安装#
[root@linuxea.com ]# go get github.com/beego/bee
go get的bee存放在当前用户的家目录,我们做软连接到环境变量
[root@linuxea.com ~]# ls -n ~/go/bin/bee /bin/
使用bee
[root@linuxea.com ~]# bee
Bee is a Fast and Flexible tool for managing your Beego Web Application.
USAGE
bee command [arguments]
AVAILABLE COMMANDS
version Prints the current Bee version
migrate Runs database migrations
api Creates a Beego API application
bale Transforms non-Go files to Go source files
fix Fixes your application by making it compatible with newer versions of Beego
dlv Start a debugging session using Delve
dockerize Generates a Dockerfile for your Beego application
generate Source code generator
hprose Creates an RPC application based on Hprose and Beego frameworks
new Creates a Beego application
pack Compresses a Beego application into a single file
rs Run customized scripts
run Run the application by starting a local development server
server serving static content over HTTP on port
Use bee help [command] for more information about a command.
ADDITIONAL HELP TOPICS
Use bee help [topic] for more information about that topic.
1.2初始化#
我们在准备阶段创建了/home/mark/,现在进入目录使用bee new创建
[root@linuxea.com ~]# cd /home/mark
[root@linuxea.com /home/mark]# bee new mark
______
| ___ \
| |_/ / ___ ___
| ___ \ / _ \ / _ \
| |_/ /| __/| __/
\____/ \___| \___| v1.10.0
2019/10/29 09:58:16 WARN ▶ 0001 You current workdir is not inside $GOPATH/src.
2019/10/29 09:58:16 INFO ▶ 0002 Creating application...
create /home/mark/src/mark/
create /home/mark/src/mark/conf/
create /home/mark/src/mark/controllers/
create /home/mark/src/mark/models/
create /home/mark/src/mark/routers/
create /home/mark/src/mark/tests/
create /home/mark/src/mark/static/
create /home/mark/src/mark/static/js/
create /home/mark/src/mark/static/css/
create /home/mark/src/mark/static/img/
create /home/mark/src/mark/views/
create /home/mark/src/mark/conf/app.conf
create /home/mark/src/mark/controllers/default.go
create /home/mark/src/mark/views/index.tpl
create /home/mark/src/mark/routers/router.go
create /home/mark/src/mark/tests/default_test.go
create /home/mark/src/mark/main.go
2019/10/29 09:58:16 SUCCESS ▶ 0003 New application successfully created!
而后切换到当前目录下的src/mark下进行启动
[root@linuxea.com /home/mark]# cd src/mark
目录结构如下
[root@linuxea.com /home/mark/src/mark]# ll
total 4
drwxr-xr-x 2 root root 22 Oct 29 09:58 conf
drwxr-xr-x 2 root root 24 Oct 29 09:58 controllers
-rw-r--r-- 1 root root 102 Oct 29 09:58 main.go
drwxr-xr-x 2 root root 6 Oct 29 09:58 models
drwxr-xr-x 2 root root 23 Oct 29 09:58 routers
drwxr-xr-x 5 root root 38 Oct 29 09:58 static
drwxr-xr-x 2 root root 29 Oct 29 09:58 tests
drwxr-xr-x 2 root root 23 Oct 29 09:58 views
工程结构如下
[root@linuxea.com /home/mark/src/mark]# tree ./
./
├── conf
│ └── app.conf
├── controllers
│ └── default.go
├── main.go
├── mark
├── models
├── routers
│ └── router.go
├── static
│ ├── css
│ ├── img
│ └── js
│ └── reload.min.js
├── tests
│ └── default_test.go
└── views
└── index.tpl
10 directories, 8 files
main.go 程序入口
conf/app.conf 配置文件
routers/router.go 路由
models modules
controllers/default.go 控制器
views 视图
static 静态文件
tests/default_test.go 测试文件
我们顺便将beego下载
[root@linuxea.com /home/mark/src/mark]# go get github.com/astaxie/beego
而后使用go build
[root@linuxea.com /home/mark/src/mark]# go build
而后启动
[root@linuxea.com /home/mark/src/mark]# ./mark
2019/10/29 10:02:06.802 [I] [asm_amd64.s:1337] http server Running on http://:8080
2019/10/29 10:02:33.797 [D] [server.go:2774] | 10.10.0.95| 200 | 5.342932ms| match| GET / r:/
2019/10/29 10:02:33.829 [D] [server.go:2774] | 10.10.0.95| 200 | 445.413µs| match| GET /static/js/reload.min.js
2019/10/29 10:02:35.500 [D] [server.go:2774] | 10.10.0.95| 200 | 2.973234ms| match| GET / r:/
2019/10/29 10:02:36.022 [D] [server.go:2774] | 10.10.0.95| 200 | 5.334997ms| match| GET / r:/
2019/10/29 10:02:36.226 [D] [server.go:2774] | 10.10.0.95| 200 | 4.9685ms| match| GET / r:/
2019/10/29 10:02:36.409 [D] [server.go:2774] | 10.10.0.95| 200 | 3.237658ms| match| GET / r:/
2019/10/29 10:02:36.621 [D] [server.go:2774] | 10.10.0.95| 200 | 6.392029ms| match| GET / r:/
放行防火墙进行访问
[root@linuxea.com /home/mark]# iptables -I INPUT 4 -p tcp --dport 8080 -j ACCEPT
端口修改可以在conf/app.conf中
[root@linuxea.com /home/mark/src/mark]# cat conf/app.conf
appname = mark
httpport = 8080
runmode = dev
实例:
appname=CMDB
runmode=dev
sessionon=true
sessionprovider=file
sessionproviderconfig=temp/session
sessionname=sid
enablexsrf=true
xsrfexpire=3600
xsrfkey=8873b558a8d5ac95675c7bb36023c434
include "db.conf"
[dev]
httpport=8080
[prod]
httpport=80
如上所示,如果runmode=dev则打开的是8080端口,如果等于prod则打开的是80端口
同时你可以使用变量,修改本地变量启动不同端口。如:
runmode=${RUNMODE||dev}
如上所示,如果RUNMODE环境变量为空,则默认使用dev。
如果使用set RUNMODE=prod
,则再次启动端口修改为80。
1.3配置文件#
- 系统默认参数
beego中带有很多配置的参数,在conf/app.conf中设置对应的值,不区分大小写,每个值也可以通过代码进行配置
- 基础配置
AppConfigPath:默认是应用程序对应的目录下的conf/app.conf
,可以在程序代码中修改beego.AppConfigPath="conf/app2.conf"
AppConfigProvider:配置文件的格式,默认是ini,可以配置为xml,yaml,json,beego.AppConfigProvider = "ini"
- App配置
AppName: 应用名称,默认是beego,通过bee new创建的是创建的项目名。beego.BConfig.AppName="beego"
RunMode: prod,dev或者test,默认是dev为开发模式,在开发模式下出错会提示友好的出错页面,beego.BConfig.RunMode="dev"
RouterCaseSensitive: 是否路由忽略大小写匹配,默认是true,区分大小写,beego.BConfig.RouterCaseSensitive=true
ServerName: beego服务器默认在http response header中输出server为beego。beego.Bconfig.ServerName="beego"
RecoverPanic: 默认值为true,出现异常通过recover恢复回来,false应用异常退出。beego.BConfig.RecoverPanic=true
CopyRequestBody:HTTP请求时,返回原始请求体数据字节,默认为true(GET or HEAD or 上传文件请求除外),beego.BConfig.CopyRequestBody=true
EnableGzip:是否开启Gzip支持,默认为false不支持gzip,一旦开启了gzip,那么在模板输出的内容会进行gzip或者zlib压缩,根据用户的Accept-Encoding来判断beego.BConfig.EnableGzip=false
MaxMemory:文件上传默认内存缓存大小,默认是1<<26(64M)。Beego.BConfig.MaxMemory=1<<26
EnableErrorsShow:是否显示系统错误信息,默认为True,beego.BConfig.EnableErrorsShow=true
- web配置
AutoRender:是否模板自动渲染,默认值是true,对于api类型的应用需设置成false,beego.BConfig.WebConfig.AutoRender=true
EnableDocs:是否开启文档内置功能,默认false,beego.BConfig.WebConfig.EnableDocs=true
FlashName:Flash数据设置时Cookie的名称,默认是BEEGO_FLASH。beego.BConfig.WebConfig.FlashName="BEEGO_FLASH"
Directoryindex: 是否开启静态目录的列表显示,默认不显示目录,返回403错误,beego.BConfig.WebConfig.DirectoryIndex=false
StaticExtensionsToGzip:允许那些后缀名的静态文件进行gzip压缩,默认支持.css和.js。beego.BConfig.WebConfig.StaticExtensionsToGzip=[]string{".css",".js"}等价config文件中StaticExtensionsToGzip=.css,.js
StaticDir:静态文件目录设置,默认是static
StaticDir = download
StaticDir = download:down download2:down2
Beego.BConfig.WebConfig.StaticDir
TemplatelLeft : 模板左标签,默认值是{{,beego.BConfig.WebConfig.TemplateLeft="{{"
templateRight : 模板右标签,默认值是}},beego.BConfig.WebConfig.TemplateRight="}}"
ViewsPath : 模板路径,默认值是views,beego.BConfig.ViewsPath="views"
EnableXSRF : 是否开启XSRF,默认为false,不开启。beego.BConfig.WebConfig.EnableSXRF=false
XSRFKEY : XSRF的key信息,默认值是beegoxsrf。EnableXSRF=true才有效。beego.BConfig.WebConfig.XSRFKEY="beegoxsrf"
XSRFExpire : XSRF过期时间,默认值是0,不过期。beego.BConfig.WebConfig.XSRFExpire=0
- 监听配置
Graceful:是否开启热升级,默认是false,关闭热升级,beego.BConfig.Listen.Graceful=false
ServerTimeOut : 设置HTTP的超时时间,默认是0,不超时,beego.BConfig.Listen.ServerTimeout=0
ListenTCP4 : 默认为tcp4,该值可以是tcp,tcp4,tcp6,unix,unixpacket之一,beego.BConfig.Listen.ListenTCP4=tcp4
EnableHTTP: 是否启用HTTP监听,默认是true,beego.BConfig.Listen.EnableHTTP=true
HTTPAddr : 应用监听地址,默认为空,监听所有网卡ip,beego.BConfig.Listen.HTTPAddr=""
HTTPPort : 应用监听端口,默认为8080,beego.BConfig.Listen.HTTPPort = 8080
EnableHTTPS : 是否启用HTTPS,默认为false关闭,当需要启用时,先设置EnableHTTPS=true,并设置HTTPSCertFile和HTTPSKeyFile ,beego.BConfig.Listen.HTTPSAddr=false
HTTPSAddr: 应用监听地址,默认为空,监听所有的网卡IP,beego.BConfig.Listen.EnableHTTPS=false
HTTPSPort : 应用监听端口,默认为10443,beego.BConfig.Listen.HTTPSPort=10443
HTTPSCertFile:开启https后,ssl证书存放路径,默认为空,beego.BConfig.Listen.HTTPSCertFile="conf/ssl.crt"
这写可以在: https://beego.me/docs/mvc/controller/config.md 查看。
2. 获取设置的配置信息#
我们开始定义一个ConfController结构体,而后定义一个get方法(get方法本身已经在beego中),通过beego.AppConfig.String获取配置文件是否有test信息。而后在main中写一个路由,只要是/,就到ConfController
package main
import (
"github.com/astaxie/beego"
)
type ConfController struct {
beego.Controller
}
func (this *ConfController) Get(){
this.Ctx.Output.Body([]byte(beego.AppConfig.String("test") + "\n"))
}
func main() {
beego.Router("/",&ConfController{})
beego.Run()
}
这里的目录是conf下的app.conf,我们在配置文件中写如test=test
,方便main中的函数读取
[root@linuxea.com /home/mark/src/mark1]# cat conf/app.conf
test = test
[root@linuxea.com /home/mark/src/mark1]# go build
[root@linuxea.com /home/mark/src/mark1]# ls
conf go.mod go.sum main.go mark1
[root@linuxea.com /home/mark/src/mark1]# ./mark1
2019/10/29 17:51:11.274 [I] [asm_amd64.s:1337] http server Running on http://:8080
2019/10/29 17:51:13.308 [D] [server.go:2774] | 127.0.0.1| 200 | 167.669µs| match| GET / r:/
2019/10/29 17:51:14.100 [D] [server.go:2774] | 127.0.0.1| 200 | 147.513µs| match| GET / r:/
2019/10/29 17:51:14.577 [D] [server.go:2774] | 127.0.0.1| 200 | 119.671µs| match| GET / r:/
2019/10/29 17:51:14.993 [D] [server.go:2774] | 127.0.0.1| 200 | 173.148µs| match| GET / r:/
2019/10/29 17:51:15.370 [D] [server.go:2774] | 127.0.0.1| 200 | 130.581µs| match| GET / r:/
[root@linuxea.com /home/mark/src/mark1]# curl 127.0.0.1:8080/
test
[root@linuxea.com /home/mark/src/mark1]# curl 127.0.0.1:8080/ -v
* About to connect() to 127.0.0.1 port 8080 (#0)
* Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.29.0
> Host: 127.0.0.1:8080
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Length: 5
< Date: Tue, 29 Oct 2019 09:53:31 GMT
< Content-Type: text/plain; charset=utf-8
<
test
* Connection #0 to host 127.0.0.1 left intact
3.GET,PUT方法#
我们定义两个方法分别是GET,PUT,当调用FixController方法的时候,会打印不同的内容
type FixController struct {
beego.Controller
}
func (this *FixController) Get(){
this.Ctx.Output.Body([]byte("hello world for Controller get"))
}
func (this *FixController) Put(){
this.Ctx.Output.Body([]byte("hello world for Controller put"))
}
func (this *FixController) Any(){
this.Ctx.Output.Body([]byte("hello world for Controller Any"))
}
在main中加上beego.Router("/fix",&FixController{})
,那么在访问的时候,就需要/fix
func main() {
beego.Router("/",&ConfController{})
beego.Router("/fix",&FixController{})
beego.Run()
}
编译
[root@linuxea.com /home/mark/src/mark1]# go build
运行
[root@linuxea.com /home/mark/src/mark1]# ./mark1
2019/10/30 11:12:12.240 [I] [asm_amd64.s:1337] http server Running on http://:8080
put
[root@linuxea.com ~]# curl -v -X PUT 127.0.0.1:8080/fix
* About to connect() to 127.0.0.1 port 8080 (#0)
* Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
> PUT /fix HTTP/1.1
> User-Agent: curl/7.29.0
> Host: 127.0.0.1:8080
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Length: 31
< Date: Wed, 30 Oct 2019 03:24:03 GMT
< Content-Type: text/plain; charset=utf-8
<
hello world for Controller put
* Connection #0 to host 127.0.0.1 left intact
get
[root@linuxea.com ~]# curl -v -X GET 127.0.0.1:8080/fix
* About to connect() to 127.0.0.1 port 8080 (#0)
* Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
> GET /fix HTTP/1.1
> User-Agent: curl/7.29.0
> Host: 127.0.0.1:8080
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Length: 31
< Date: Wed, 30 Oct 2019 03:24:19 GMT
< Content-Type: text/plain; charset=utf-8
<
hello world for Controller get
* Connection #0 to host 127.0.0.1 left intact
4.通配符#
如下:
type RController struct {
beego.Controller
}
func (this *RController) Get(){
id := this.Ctx.Input.Param(":id")
if id != "" {
this.Ctx.Output.Body([]byte("id in regex:" + this.Ctx.Input.Param(":id")))
}else{
this.Ctx.Output.Body([]byte("id in regex is empty"))
}
}
在main函数中使用如下进行调用
func main(){
beego.Router("/api/?:id",&RController{})
beego.Router("/api1/:id",&RController{})
beego.Router("/api2/:id([0-9]+)",&RController{})
beego.Router("/api3/:id([\\w]+)",&RController{})
beego.Router("/api4/:id:int",&RController{})
beego.Router("/api5/:id:string",&RController{})
beego.Router("/prefix/abc:id:int",&RController{})
beego.Run()
}
进行curl
[root@linuxea.com /home/mark/src/1105-2]# curl -X GET 127.0.0.1:8080/api/12
id in regex:12
[root@linuxea.com /home/mark/src/1105-2]# curl -X GET 127.0.0.1:8080/api1/12
id in regex:12
[root@linuxea.com /home/mark/src/1105-2]# curl -X GET 127.0.0.1:8080/api2/12
id in regex:12
[root@linuxea.com /home/mark/src/1105-2]# curl -X GET 127.0.0.1:8080/api3/12
id in regex:12
5.自动路由#
如下:
type SelfDefineController struct {
beego.Controller
}
func (this *SelfDefineController) ForGet(){
if strings.ToLower(this.Ctx.Input.Method()) == "get" {
this.Ctx.Output.Body([]byte("Yes,It's get"))
}
}
在main函数中
beego.AutoRouter(&SelfDefineController{})
beego.Include(&SelfDefineController{})
运行
[root@linuxea.com /home/mark/src/1105-2]# curl -X GET 127.0.0.1:8080/selfdefine
Yes,It's get
[root@linuxea.com /home/mark/src/1105-2]# curl -X GET 127.0.0.1:8080/selfdefine/forget
Yes,It's get
6.bool传递#
结构体如下:
type ParamsController struct {
beego.Controller
}
如果传入的是bool,就打印No bool value
func (this *ParamsController) HandleParams(){
output := fmt.Sprintf("%T %v\n",this.GetString("string"),this.GetString("string"))
output += fmt.Sprintf("%T %v\n",this.GetStrings("string"),this.GetStrings("string"))
boolValue,err := this.GetBool("bool")
if err != nil{
output += fmt.Sprintf("%T %v\n",boolValue,boolValue)
}else{
output += fmt.Sprintf("No bool value\n")
}
this.Ctx.Output.Body([]byte(output))
}
如下:
[root@linuxea.com ~]# curl localhost:8080/params?bool=true
string
[]string []
No bool value
[root@linuxea.com ~]# curl localhost:8080/params?string=111
string 111
[]string [111]
bool false
[root@linuxea.com ~]# curl localhost:8080/params?strings=111
string
[]string []
bool false
7.POST以项目表单的方式传递#
定义结构体
type user struct {
Id int `form:"-"`
Name interface{} `form:"username"`
Age int `form:"age"`
Email string
}
编写一个HandleForm的方法,而后在main中调用
func (this *ParamsController) HandleForm(){
u := user{}
this.ParseForm(&u)
this.Ctx.Output.Body([]byte(fmt.Sprintf("%+v\n",u)))
}
main
beego.Router("/form",&ParamsController{},"get,post:HandleForm")
如下:
-F就是以Form表达的形式进行传递
[root@linuxea.com ~]# curl -X POST -F"username=mark" -F"age=18" -F"Email=q@1" localhost:8080/form
{Id:0 Name:mark Age:18 Email:q@1}
8.Json方式传递#
func (this *ParamsController) HandleBody(){
u := user{}
err := json.Unmarshal(this.Ctx.Input.RequestBody,&u)
if err != nil {
this.Ctx.Output.Body([]byte(fmt.Sprintf("%v\n",err)))
}else{
this.Ctx.Output.Body([]byte(fmt.Sprintf("%+v\n",u)))
}
}
创建一个json文件
[root@linuxea.com /home/mark/src/1105-3]# cat test.json
{
"Id":0,
"Name":"mark",
"Age":18,
"Email":"q@1"
}
在配置文件中添加copyrequestbody = true
选项,而后传递即可
[root@linuxea.com /home/mark/src/1105-3]# curl -X POST -d@test.json localhost:8080/body
{Id:0 Name:mark Age:18 Email:q@1}
9.上传#
uploads,如果err等于nil,就上传到/Users/uploads/,上传没有报错就返回ok
func (this *ParamsController) HandleFile(){
f,h,err := this.GetFile("uploadname")
if err != nil{
this.Ctx.Output.Body([]byte(fmt.Sprintf("%v\n",err)))
}else {
defer f.Close()
err := this.SaveToFile("uploadname","/Users/uploads/"+h.Filename)
if err == nil {
this.Ctx.Output.Body([]byte("ok"))
}else {
this.Ctx.Output.Body([]byte(fmt.Sprintf("%v\n",err)))
}
}
}
main中
beego.Router("/file",&ParamsController{},"get,post:HandleFile")
curl下
[root@linuxea.com /home/mark/src/1105-3]# curl localhost:8080/file -F"uploadname=@//home/mark/src/1105-3/test.json"
ok
已经上传到/opt/uploads/下
[root@linuxea.com /home/mark/src/1105-3]# ll /opt/uploads/
total 8
-rw-r--r-- 1 root root 55 Nov 6 15:06 test.json
如下
[root@linuxea.com /home/mark/src/1105-3]# cat /opt/uploads/test.json
{
"Id":0,
"Name":"mark",
"Age":18,
"Email":"q@1"
}