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

20191029

端口修改可以在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"

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

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"
}

10.model-orm#