一些杂项例子(miscellaneous)

1.文件日志记录(file logger)

目录结构

主目录fileLogger

  1. —— main.go

代码示例

main.go

  1. package main
  2. import (
  3. "os"
  4. "time"
  5. "github.com/kataras/iris"
  6. )
  7. //根据日期获取文件名,仅用于容易区分
  8. func todayFilename() string {
  9. today := time.Now().Format("Jan 02 2006")
  10. return today + ".txt"
  11. }
  12. func newLogFile() *os.File {
  13. filename := todayFilename()
  14. //打开文件,如果服务器重新启动,这将附加到今天的文件。
  15. f, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
  16. if err != nil {
  17. panic(err)
  18. }
  19. return f
  20. }
  21. func main() {
  22. f := newLogFile()
  23. defer f.Close()
  24. app := iris.New()
  25. //将文件作为记录器附加,请记住,iris的app logger只是一个io.Writer。
  26. //如果需要同时将日志写入文件和控制台,请使用以下代码。
  27. // app.Logger().SetOutput(io.MultiWriter(f, os.Stdout))
  28. app.Logger().SetOutput(f)
  29. app.Get("/ping", func(ctx iris.Context) {
  30. // for the sake of simplicity, in order see the logs at the ./_today_.txt
  31. ctx.Application().Logger().Infof("Request path: %s", ctx.Path())
  32. ctx.WriteString("pong")
  33. })
  34. //访问http://localhost:8080/ping
  35. //打开文件 ./logs{TODAY}.txt file.
  36. if err := app.Run(iris.Addr(":8080"), iris.WithoutBanner, iris.WithoutServerError(iris.ErrServerClosed)); err != nil {
  37. app.Logger().Warn("Shutdown with error: " + err.Error())
  38. }
  39. }

2.多语言切换(i18n)

目录结构

主目录i18n

  1. —— locales
  2. —— locale_el-GR.ini
  3. —— locale_en-US.ini
  4. —— locale_zh-CN.ini
  5. —— main.go
  6. —— main_test.go

代码示例

main.go

  1. package main
  2. import (
  3. "github.com/kataras/iris"
  4. "github.com/kataras/iris/middleware/i18n"
  5. )
  6. func newApp() *iris.Application {
  7. app := iris.New()
  8. globalLocale := i18n.New(i18n.Config{
  9. Default: "en-US",
  10. URLParameter: "lang",
  11. Languages: map[string]string{
  12. "en-US": "./locales/locale_en-US.ini",
  13. "el-GR": "./locales/locale_el-GR.ini",
  14. "zh-CN": "./locales/locale_zh-CN.ini"}})
  15. app.Use(globalLocale)
  16. app.Get("/", func(ctx iris.Context) {
  17. //它试图通过以下方式找到当前语言环境值:
  18. // ctx.Values().GetString("language")
  19. //如果是空的那么它尝试从配置中设置的URLParameter中查找
  20. //如果没找到的话
  21. //它试图通过("language")cookie找到语言环境值
  22. //如果没有找到,则将其设置为配置上设置的默认值
  23. // hi是键,'iris'是.ini文件中的%s,可以叫参数
  24. //第二个参数是可选的
  25. // hi := ctx.Translate("hi", "iris")
  26. // 或:
  27. hi := i18n.Translate(ctx, "hi", "iris")
  28. language := ctx.Values().GetString(ctx.Application().ConfigurationReadOnly().GetTranslateLanguageContextKey())
  29. //返回'en-US'的形式
  30. //找到的第一个默认语言保存在名称为("language")的cookie中,
  31. //你可以通过改变:iris.TranslateLanguageContextKey的值来改变它
  32. ctx.Writef("From the language %s translated output: %s", language, hi)
  33. })
  34. multiLocale := i18n.New(i18n.Config{
  35. Default: "en-US",
  36. URLParameter: "lang",
  37. Languages: map[string]string{
  38. "en-US": "./locales/locale_multi_first_en-US.ini, ./locales/locale_multi_second_en-US.ini",
  39. "el-GR": "./locales/locale_multi_first_el-GR.ini, ./locales/locale_multi_second_el-GR.ini"}})
  40. app.Get("/multi", multiLocale, func(ctx iris.Context) {
  41. language := ctx.Values().GetString(ctx.Application().ConfigurationReadOnly().GetTranslateLanguageContextKey())
  42. fromFirstFileValue := i18n.Translate(ctx, "key1")
  43. fromSecondFileValue := i18n.Translate(ctx, "key2")
  44. ctx.Writef("From the language: %s, translated output:\n%s=%s\n%s=%s",
  45. language, "key1", fromFirstFileValue,
  46. "key2", fromSecondFileValue)
  47. })
  48. return app
  49. }
  50. func main() {
  51. app := newApp()
  52. // 访问 http://localhost:8080/?lang=el-GR
  53. // 或 http://localhost:8080 (default is en-US)
  54. // 或 http://localhost:8080/?lang=zh-CN
  55. // 访问 http://localhost:8080/multi?lang=el-GR
  56. // 或 http://localhost:8080/multi (default is en-US)
  57. // 或 http://localhost:8080/multi?lang=en-US
  58. // 或使用cookie来设置语言.
  59. app.Run(iris.Addr(":8080"))
  60. }

main_test.go(测试代码)

  1. package main
  2. import (
  3. "fmt"
  4. "testing"
  5. "github.com/kataras/iris/httptest"
  6. )
  7. func TestI18n(t *testing.T) {
  8. app := newApp()
  9. expectedf := "From the language %s translated output: %s"
  10. var (
  11. elgr = fmt.Sprintf(expectedf, "el-GR", "γεια, iris")
  12. enus = fmt.Sprintf(expectedf, "en-US", "hello, iris")
  13. zhcn = fmt.Sprintf(expectedf, "zh-CN", "您好,iris")
  14. elgrMulti = fmt.Sprintf("From the language: %s, translated output:\n%s=%s\n%s=%s", "el-GR",
  15. "key1",
  16. "αυτό είναι μια τιμή από το πρώτο αρχείο: locale_multi_first",
  17. "key2",
  18. "αυτό είναι μια τιμή από το δεύτερο αρχείο μετάφρασης: locale_multi_second")
  19. enusMulti = fmt.Sprintf("From the language: %s, translated output:\n%s=%s\n%s=%s", "en-US",
  20. "key1",
  21. "this is a value from the first file: locale_multi_first",
  22. "key2",
  23. "this is a value from the second file: locale_multi_second")
  24. )
  25. e := httptest.New(t, app)
  26. // default is en-US
  27. e.GET("/").Expect().Status(httptest.StatusOK).Body().Equal(enus)
  28. // default is en-US if lang query unable to be found
  29. e.GET("/").Expect().Status(httptest.StatusOK).Body().Equal(enus)
  30. e.GET("/").WithQueryString("lang=el-GR").Expect().Status(httptest.StatusOK).
  31. Body().Equal(elgr)
  32. e.GET("/").WithQueryString("lang=en-US").Expect().Status(httptest.StatusOK).
  33. Body().Equal(enus)
  34. e.GET("/").WithQueryString("lang=zh-CN").Expect().Status(httptest.StatusOK).
  35. Body().Equal(zhcn)
  36. e.GET("/multi").WithQueryString("lang=el-GR").Expect().Status(httptest.StatusOK).
  37. Body().Equal(elgrMulti)
  38. e.GET("/multi").WithQueryString("lang=en-US").Expect().Status(httptest.StatusOK).
  39. Body().Equal(enusMulti)
  40. }

/locales/locale_el-GR.ini(语言包)

  1. hi = γεια, %s

/locales/locale_en-US.ini(语言包)

  1. hi = hello, %s

/locales/locale_zh-CN.ini(语言包)

  1. hi = 您好,%s

3.代码性能测试(pprof)

目录结构

主目录pprof

  1. —— main.go

代码示例

main.go

  1. //go中有pprof包来做代码的性能监控
  2. package main
  3. import (
  4. "github.com/kataras/iris"
  5. "github.com/kataras/iris/middleware/pprof"
  6. )
  7. func main() {
  8. app := iris.New()
  9. app.Get("/", func(ctx iris.Context) {
  10. ctx.HTML("<h1> Please click <a href='/debug/pprof'>here</a>")
  11. })
  12. app.Any("/debug/pprof/{action:path}", pprof.New())
  13. app.Run(iris.Addr(":8080"))
  14. }

4.图形验证码(recaptcha)

目录结构

主目录recaptcha

  1. —— custom_form
  2. —— main.go
  3. —— main.go

代码示例

main.go

  1. package main
  2. import (
  3. "github.com/kataras/iris"
  4. "github.com/kataras/iris/middleware/recaptcha"
  5. )
  6. //密钥应通过https://www.google.com/recaptcha获取
  7. const (
  8. recaptchaPublic = ""
  9. recaptchaSecret = ""
  10. )
  11. func showRecaptchaForm(ctx iris.Context, path string) {
  12. ctx.HTML(recaptcha.GetFormHTML(recaptchaPublic, path))
  13. }
  14. func main() {
  15. app := iris.New()
  16. // On both Get and Post on this example, so you can easly
  17. // use a single route to show a form and the main subject if recaptcha's validation result succeed.
  18. //在此示例的Get和Post上,您可以轻松
  19. //使用单个路径显示表单,并且重新验证结果的主要主题成功。
  20. app.HandleMany("GET POST", "/", func(ctx iris.Context) {
  21. if ctx.Method() == iris.MethodGet {
  22. showRecaptchaForm(ctx, "/")
  23. return
  24. }
  25. result := recaptcha.SiteFerify(ctx, recaptchaSecret)
  26. if !result.Success {
  27. /* 如果你想要或什么都不做,重定向到这里 */
  28. ctx.HTML("<b> failed please try again </b>")
  29. return
  30. }
  31. ctx.Writef("succeed.")
  32. })
  33. app.Run(iris.Addr(":8080"))
  34. }

/custom_form/main.go

  1. package main
  2. import (
  3. "fmt"
  4. "github.com/kataras/iris"
  5. "github.com/kataras/iris/middleware/recaptcha"
  6. )
  7. //密钥应通过https://www.google.com/recaptcha获取
  8. const (
  9. recaptchaPublic = "6Lf3WywUAAAAAKNfAm5DP2J5ahqedtZdHTYaKkJ6"
  10. recaptchaSecret = "6Lf3WywUAAAAAJpArb8nW_LCL_PuPuokmEABFfgw"
  11. )
  12. func main() {
  13. app := iris.New()
  14. r := recaptcha.New(recaptchaSecret)
  15. app.Get("/comment", showRecaptchaForm)
  16. //在主处理程序之前传递中间件或使用`recaptcha.SiteVerify`。
  17. app.Post("/comment", r, postComment)
  18. app.Run(iris.Addr(":8080"))
  19. }
  20. var htmlForm = `<form action="/comment" method="POST">
  21. <script src="https://www.google.com/recaptcha/api.js"></script>
  22. <div class="g-recaptcha" data-sitekey="%s"></div>
  23. <input type="submit" name="button" value="Verify">
  24. </form>`
  25. func showRecaptchaForm(ctx iris.Context) {
  26. contents := fmt.Sprintf(htmlForm, recaptchaPublic)
  27. ctx.HTML(contents)
  28. }
  29. func postComment(ctx iris.Context) {
  30. // [...]
  31. ctx.JSON(iris.Map{"success": true})
  32. }

5.异常恢复(recover)

目录结构

主目录recover

  1. —— main.go

代码示例

main.go

  1. package main
  2. import (
  3. "github.com/kataras/iris"
  4. "github.com/kataras/iris/middleware/recover"
  5. )
  6. func main() {
  7. app := iris.New()
  8. app.Use(recover.New())
  9. i := 0
  10. //让我们在下一个请求时模拟panic
  11. app.Get("/", func(ctx iris.Context) {
  12. i++
  13. if i%2 == 0 {
  14. panic("a panic here")
  15. }
  16. ctx.Writef("Hello, refresh one time more to get panic!")
  17. })
  18. // http://localhost:8080, 刷新5-6次
  19. app.Run(iris.Addr(":8080"))
  20. }
  21. //注意: app := iris.Default()而不是iris.New()自动使用恢复中间件。