iris框架的路由功能,支持静态路由和动态路由两种方式。静态路由就是定义的路径是固定的,只有通过固定的路径才能访问到页面内容。动态的路由,顾名思义,就是路径可以动态变化。

iris自定义了一些基本的宏,可以动态的解析常用的参数类型,如果常用的宏定义不能满足需求,我们还可以使用自定义函数来完成动态路由的定义。

动态路由的定义

常用的路由宏定义有:

  • string参数
{param:string}

这是最基本的定义,定义一个参数,它的类型为string类型。同样地,它还可以简写为{param},即{param} == {param:string}。也就是说,如果类型为string,可以省略类型的定义,它默认会解析为string。


- 整形参数

```golang
{param:int}

整形参数它只支持0-9的数字,如果不是0-9,它就不会匹配到这个路径。

  • 长整形 int64 参数
{param:long}

同样,长整形参数它也只支持0-9的数字,如果不是0-9,它就不会匹配到这个路径。

  • 布朗值参数
{param:boolean}

布朗值参数支持如下形式的值:"1"、"t"、"T"、"TRUE"、"true"、"True" or "0"、"f"、"F"、"FALSE"、"false"、"False"。只有路径是这些值的时候,它才会匹配到。

  • 字母参数
{param:alphabetical}

之母参数只支持大写或小写字母。

  • 文件名参数
{param:file}

它支持包含数字0-9、字母a-z或A-Z、下划线_、中划线-、点. 这些字符组成的路径,它不支持中文。

  • 路径参数
{param:path}

所谓路径参数,就是整个路径,即uri。除了域名和协议外的都叫做路径。比如https://www.kandaoni.com/article/1.html,它将完整的匹配到/article/1.html

  • 自定义参数

自定义参数定义需要先引入github.com/kataras/iris/macro。然后将自定义匹配参数的函数注册到macro中。

import "github.com/kataras/iris/macro"
macro.Int.RegisterFunc("min", func(minValue int) func(string) bool {
    return  func(paramValue string) bool {
        n, err  := strconv.Atoi(paramValue)
        if err !=  nil {
            return  false
        }
        return n >= minValue
    }
})

比如这里定义了一个min类型的参数,它支持传入一个指定的数值,如果路径中匹配到大于等于这个值的时候,它就会匹配成功。比如{id:int min(1)}则路径的值大于等于1的时候,才会匹配成功。

路由参数的获取

路由的参数获取需要使用ctx.Params()

// /category/1
app.Get("/category/{id:int}", func(ctx iris.Context) {
    id, _ := ctx.Params().GetInt("id")
    ctx.Writef("整形参数匹配到的值是:%d", id)
})
// /success/false
app.Get("/success/id:boolean", func(ctx iris.Context) {
    id, _ := ctx.Params().GetInt("id")
    ctx.Writef("整形参数匹配到的值是:%d", id)
})
// /account/sinclair
app.Get("/account/{name}", func(ctx iris.Context) {
    ctx.Writef("Hello %s", ctx.Params().Get("name"))
})
// /account/sinclair
app.Get("/account/{name:alphabetical}", func(ctx iris.Context) {
    ctx.Writef("Hello %s", ctx.Params().Get("name"))
})
// /thumb/images/aa.png
app.Get("/thumb/{directory:path}", func(ctx iris.Context) {
    ctx.Writef("路径参数匹配到的值是:%s", ctx.Params().Get("directory"))
})
// /article/1 如果错误抛出504错误。
app.Get("/article/{id:int min(1) else 504}", func(ctx iris.Context) {
    id, _ := ctx.Params().GetInt("id")
    ctx.Writef("整形参数并使用了已定义min宏获取到的值是:%d", id)
}) 

注意:一个路径参数名称应该只包含小写字母,像 _ 和数字这样的符号是 不允许的。

也不要困惑 ctx.Params() 和 ctx.Values()。路径参数值获取通过 ctx.Params(),上下文中用于处理器之间通信的局部存储和中间件使用 ctx.Values()。

iris路由的路径匹配,它不支持参数跟字符串组合,比如/article/123.html它不支持写成/article/{id:int}.html。这么写是错误的,这个路由无法被匹配到。它只能通过/article/{slug:string}来匹配全部,然后再在控制器里用正则来区分:

slug := ctx.Params().Get("slug")
reg := regexp.MustCompile(`(\d+)\.html`)
match := reg.FindStringSubmatch(slug)
var id int
if len(match) > 1 {
  //获取到id 的情况
  id, _ := strconv.Atoi(match[1])
} else {
  //另一种情况
}

表单数据的读取

iris 的表单获取有几种形式,一种是get表单提交的时候,获取url参数:

//获取string类型的url参数
ctx.URLParam("id")
//获取清除空格等无效字符的string类型的url参数
ctx.URLParamTrim("id")
//获取转义后的url参数
ctx.URLParamEscape("id")
ctx.URLParamInt("id")
...

url参数获取可以获取到string类型、int类型、boolean类型、int64类等,具体根据实际需要来获取,也可以获取后再通过转换函数来转换

同样,post表单提交的时候,可以这样获取参数

//获取string类型的post参数
ctx.PostValue("id")
//获取清除空格等无效字符的string类型的post参数
ctx.PostValueTrim("id")
ctx.PostValueInt("id")

post参数获取方式跟url参数获取方式大同小异,只是各边函数没有。同样可以获取到string类型、int类型、boolean类型、int64类等的参数值。

上面是单个参数的获取,我们还可以使用定义好的结构体将参数读入结构体中,来保证数据的完整性。不如前面章节中,我们登陆的时候定义的管理员提交表单的结构体:

type Admin struct {
	UserName string `form:"user_name" validate:"required"`
	Password string `form:"password" validate:"required"`
}

这是一个form表单,定义了他们是必填参数。

iris的控制器中,读取不同类型提交的表单,读取的方式也不一样。读取get提交的表单使用ctx.ReadQuery(&req)

var req request.Admin
ctx.ReadQuery(&req)

读取post提交的form表单使用ctx.ReadForm(&req)

var req request.Admin
ctx.ReadForm(&req)

读取post提交的json数据使用:ctx.ReadJSON(&req)

var req request.Admin
ctx.ReadJSON(&req)

读取post提交的xml数据使用:ctx.ReadXML(&req)

var req request.Admin
ctx.ReadXML(&req)

读取post提交的yaml数据使用:ctx.ReadYAML(&req)

var req request.Admin
ctx.ReadYAML(&req)

如果提交的是json数据,我们还可以直接读取body,通过ctx.UnmarshalBody(&req)来解析提交的数据。

完整的项目示例代码托管在GitHub上,需要查看完整的项目代码可以到github.com/fesiong/goblog 上查看,也可以直接fork一份来在上面做修改。