GoFrame GoFrame - 数据返回管理

gqcn · 2020年02月12日 · 917 次阅读

基本介绍

ghttp.Response对象实现了标准库的http.ResponseWriter接口。数据输出使用Write*相关方法实现,并且数据输出采用了Buffer机制,因此数据的处理效率比较高。任何时候可以通过OutputBuffer方法输出缓冲区数据到客户端,并清空缓冲区数据。

接口文档:https://godoc.org/github.com/gogf/gf/net/ghttp#Response

简要说明:

  1. Write*方法用于数据的输出,可为任意的数据格式,内部通过断言对参数做自动分析。
  2. Write*Exit方法用于数据输出后退出当前服务方法,可用于替代return返回方法。
  3. WriteJson*/WriteXml方法用于特定数据格式的输出,这是为开发者提供的简便方法。
  4. WriteTpl*方法用于模板输出,解析并输出模板文件,也可以直接解析并输出给定的模板内容。
  5. ParseTpl*方法用于模板解析,解析模板文件或者模板内容,返回解析后的内容。
  6. 其他方法详见接口文档;

此外,需要提一下,Header的操作可以通过标准库的方法来实现,例如:

Response.Header().Set("Content-Type", "text/plain; charset=utf-8")

缓冲控制

接口文档:https://godoc.org/github.com/gogf/gf/net/ghttp#Response

Response输出采用了缓冲控制,输出的内容预先写入到一块缓冲区,等待服务方法执行完毕后才真正地输出到客户端。该特性在提高执行效率同时为输出内容的控制提供了更高的灵活性。

相关方法:

func (r *Response) Buffer() []byte
func (r *Response) BufferString() string
func (r *Response) BufferLength() int
func (r *Response) SetBuffer(data []byte)
func (r *Response) ClearBuffer()
func (r *Response) Output()

其中Output作用类似于Flush将缓冲区的数据输出到客户端并清空缓冲区。

举个例子:

我们通过后置中间件统一对返回的数据做处理,如果服务方法产生了异常,那么不能将敏感错误信息推送到客户端,而统一设置错误提示信息。

package main

import (
    "github.com/gogf/gf/frame/g"
    "github.com/gogf/gf/net/ghttp"
    "net/http"
)

func MiddlewareErrorHandler(r *ghttp.Request) {
    r.Middleware.Next()
    if r.Response.Status >= http.StatusInternalServerError {
        r.Response.ClearBuffer()
        r.Response.Writeln("服务器居然开小差了,请稍后再试吧!")
    }
}

func main() {
    s := g.Server()
    s.Group("/api.v2", func(group *ghttp.RouterGroup) {
        group.Middleware(MiddlewareErrorHandler)
        group.ALL("/user/list", func(r *ghttp.Request) {
            panic("db error: sql is xxxxxxx")
        })
    })
    s.SetPort(8199)
    s.Run()
}

访问 http://127.0.0.1:8199/api.v2/user/list 可以看到,页面输出了:

服务器居然开小差了,请稍后再试吧!

JSON/XML输出

接口文档:https://godoc.org/github.com/gogf/gf/net/ghttp#Response

Response提供了对JSON/XML数据格式输出的原生支持,通过以下方法实现:

  1. WriteJson* 方法用于返回JSON数据格式,参数为任意类型,可以为stringmapstruct等等。返回的Content-Typeapplication/json
  2. WriteXml* 方法用于返回XML数据格式,参数为任意类型,可以为stringmapstruct等等。返回的Content-Typeapplication/xml

JSON数据格式支持的同时,同时也支持JSONP协议。

JSON

package main

import (
    "github.com/gogf/gf/frame/g"
    "github.com/gogf/gf/net/ghttp"
)

func main() {
    s := g.Server()
    s.Group("/", func(group *ghttp.RouterGroup) {
        group.ALL("/json", func(r *ghttp.Request) {
            r.Response.WriteJson(g.Map{
                "id":   1,
                "name": "john",
            })
        })
    })
    s.SetPort(8199)
    s.Run()
}

执行后,我们通过curl工具测试下:

$ curl -i http://127.0.0.1:8199/json
HTTP/1.1 200 OK
Content-Type: application/json
Server: GF HTTP Server
Date: Sun, 05 Jan 2020 02:49:31 GMT
Content-Length: 22

{"id":1,"name":"john"}

JSONP

需要注意使用JSONP协议时必须通过Query方式提供callback参数。

package main

import (
    "github.com/gogf/gf/frame/g"
    "github.com/gogf/gf/net/ghttp"
)

func main() {
    s := g.Server()
    s.Group("/", func(group *ghttp.RouterGroup) {
        group.ALL("/jsonp", func(r *ghttp.Request) {
            r.Response.WriteJsonP(g.Map{
                "id":   1,
                "name": "john",
            })
        })
    })
    s.SetPort(8199)
    s.Run()
}

执行后,我们通过curl工具测试下:

$ curl -i "http://127.0.0.1:8199/jsonp?callback=MyCallback"
HTTP/1.1 200 OK
Server: GF HTTP Server
Date: Sun, 05 Jan 2020 02:50:42 GMT
Content-Length: 34
Content-Type: text/plain; charset=utf-8

MyCallback({"id":1,"name":"john"})

XML

package main

import (
    "github.com/gogf/gf/frame/g"
    "github.com/gogf/gf/net/ghttp"
)

func main() {
    s := g.Server()
    s.Group("/", func(group *ghttp.RouterGroup) {
        group.ALL("/xml", func(r *ghttp.Request) {
            r.Response.Write(`<?xml version="1.0" encoding="UTF-8"?>`)
            r.Response.WriteXml(g.Map{
                "id":   1,
                "name": "john",
            })
        })
    })
    s.SetPort(8199)
    s.Run()
}

执行后,我们通过curl工具测试下:

$ curl -i http://127.0.0.1:8199/xml
HTTP/1.1 200 OK
Content-Type: application/xml
Server: GF HTTP Server
Date: Sun, 05 Jan 2020 03:00:55 GMT
Content-Length: 76

<?xml version="1.0" encoding="UTF-8"?><doc><id>1</id><name>john</name></doc>

模板解析

接口文档:https://godoc.org/github.com/gogf/gf/net/ghttp#Response

Response支持模板文件/内容解析输出,或者模板文件/内容解析返回。与直接使用模板对象解析模板功能不同的是,Response的解析支持一些请求相关的内置变量。模板解析包含以下方法:

  1. WriteTpl*方法用于模板输出,解析并输出模板文件,也可以直接解析并输出给定的模板内容。
  2. ParseTpl*方法用于模板解析,解析模板文件或者模板内容,返回解析后的内容。

内置变量

Config

访问默认的配置管理(config.toml)对象配置项。

使用方式

{{.Config.配置项}}

访问当前请求的Cookie对象参数值。

使用方式

{{.Cookie.键名}}

Session

访问当前请求的Session对象参数值。

使用方式

{{.Session.键名}}

Query

访问当前Query String中的请求参数值。

使用方式

{{.Query.键名}}

Form

访问当前表单请求参数值。

使用方式

{{.Form.键名}}

Request

访问当前请求参数值(不区分参数提交方式)。

使用方式

{{.Request.键名}}

使用示例

package main

import (
    "github.com/gogf/gf/frame/g"
    "github.com/gogf/gf/net/ghttp"
)

func main() {
    s := g.Server()
    s.BindHandler("/", func(r *ghttp.Request){
        r.Cookie.Set("theme", "default")
        r.Session.Set("name", "john")
        content :=`Config:{{.Config.redis.cache}}, Cookie:{{.Cookie.theme}}, Session:{{.Session.name}}, Query:{{.Query.name}}`
        r.Response.WriteTplContent(content, nil)
    })
    s.SetPort(8199)
    s.Run()
}

其中,config.toml内容为:

# Redis数据库配置
[redis]
    disk  = "127.0.0.1:6379,0"
    cache = "127.0.0.1:6379,1"

执行后,访问 http://127.0.0.1:8199/?name=john ,输出结果为:

Config:127.0.0.1:6379,1, Cookie:default, Session:john, Query:john
更多原创文章干货分享,请关注公众号
  • 加微信实战群请加微信(注明:实战群):gocnio
暂无回复。
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册