相关方法:

func (r *Response) WriteJson(content interface{}) error
func (r *Response) WriteJsonExit(content interface{}) error
func (r *Response) WriteJsonP(content interface{}) error
func (r *Response) WriteJsonPExit(content interface{}) error
func (r *Response) WriteXml(content interface{}, rootTag ...string) error
func (r *Response) WriteXmlExit(content interface{}, rootTag ...string) error

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/v2/frame/g"
	"github.com/gogf/gf/v2/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/v2/frame/g"
	"github.com/gogf/gf/v2/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/v2/frame/g"
	"github.com/gogf/gf/v2/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>
Content Menu

  • No labels

5 Comments

  1. WriteJson方法返回的json数据如果有中文的话会出现乱码现象,在Safari浏览器显示不正确,其他浏览器没问题,请教下这个应该如何处理呢
    r.Response.WriteJson(g.Map{
    "code": 200,
    "msg": "获取数据成功",
    "data": g.Array{g.Map{"ms1":"133"}},
    })

    1. 在其他文档下发现了别人的回答,添加一个全局的后置中间件

      func Middleware(r *ghttp.Request) {
      r.Middleware.Next()
      // 中间件处理逻辑
      r.Response.Header().Set("Content-Type","application/json;charset=utf-8")
      }

      // 注册全局中间件
      s.Use(Middleware)
  2. 强哥 郭强  请问WirteJson 怎么设置大数字为字符串,类似 通用编解码-FAQ 中 JSON中的大数字精度丢失问题 uint64 应该都是大数字,如:SnowflakeID 

    目前的做法只能在对应的结构体上写入  json 标签是加入 string 标识,如下

    type RefreshRes struct {
    	ID uint64 `json:"id,string" description:"刷新请求ID"` // 刷新请求ID
    }


    是否支持全局设置大数字自动设置为 string ,WirteJson 调用 `gf.json`包,底层直接调用 json.Marshal




  3. // 登录成功后返回token
    func PersonLoginAfter(r *ghttp.Request, respData gtoken.Resp) {
        if respData.Success() {
            r.Response.WriteJsonExit(g.Map{
                "state":   consts.SUCCESS,
                "message": "登录成功!",
                "data":    respData.GetString(gtoken.KeyToken), // 登录成功后data中存放了token
            })
        } else {
            r.Response.WriteJsonExit(g.Map{
                "state":   consts.ERROR,
                "message": "登录失败!",
            })
        }
    }

    为什么前端收到的json最后有4个字符null??例如:
    res: {"data":"lUZ5V4m1yfFIniYE5PNpLKCUPdYG2qcBrcYijM4klsS6wZIKfs0Py/JZ0xRcga1w","message":"登录成功!","state":1}null

    然后就因为null这4个字符,前端反序列化失败,然后要做字符串截取去掉这4个字符,再反序列化,真奇怪!

    另外我有个后置中间件,代码如下:
    // HandleReturn 后置中间件:处理返回数据
    func (s *middlewareService) HandleReturn(r *ghttp.Request) {
        r.Middleware.Next()
        err := r.GetError()
        if err != nil {
            r.Response.WriteJsonExit(g.Map{
                "state":   consts.ERROR,
                "message": err.Error(),
            })
        } else {
            r.Response.WriteJsonExit(r.GetHandlerResponse())
        }
    }会是这个出问题了?

  4. WriteJsonExit执行以后,后置中间件的代码还会执行么??