GoFrame v1.11版本开始,Request对象提供了对客户端提交的JSON/XML数据格式的原生支持,为开发者提供了更便捷的数据获取特性,以进一步提高开发效率。

示例1,简单示例

package main

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

func main() {
	s := g.Server()
	s.BindHandler("/", func(r *ghttp.Request) {
		r.Response.Writef("name: %v, pass: %v", r.Get("name"), r.Get("pass"))
	})
	s.SetPort(8199)
	s.Run()
}

执行后,我们通过curl工具提交数据来测试一下:

  1. Query数据格式

    $ curl "http://127.0.0.1:8199/?name=john&pass=123"
    name: john, pass: 123
  2. Form表单提交

    $ curl -d "name=john&pass=123" "http://127.0.0.1:8199/"
    name: john, pass: 123
  3. JSON数据格式

    $ curl -d '{"name":"john","pass":"123"}' "http://127.0.0.1:8199/"
    name: john, pass: 123
  4. XML数据格式

    $ curl -d '<?xml version="1.0" encoding="UTF-8"?><doc><name>john</name><pass>123</pass></doc>' "http://127.0.0.1:8199/"
    name: john, pass: 123
    
    
    $ curl -d '<doc><name>john</name><pass>123</pass></doc>' "http://127.0.0.1:8199/"
    name: john, pass: 123

示例2,对象转换及校验

package main

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

type RegisterReq struct {
	Name  string `p:"username"  v:"required|length:6,30#请输入账号|账号长度为:{min}到:{max}位"`
	Pass  string `p:"password1" v:"required|length:6,30#请输入密码|密码长度不够"`
	Pass2 string `p:"password2" v:"required|length:6,30|same:password1#请确认密码|密码长度不够|两次密码不一致"`
}

type RegisterRes struct {
	Code  int         `json:"code"`
	Error string      `json:"error"`
	Data  interface{} `json:"data"`
}

func main() {
	s := g.Server()
	s.BindHandler("/register", func(r *ghttp.Request) {
		var req *RegisterReq
		if err := r.Parse(&req); err != nil {
			// Validation error.
			if v, ok := err.(gvalid.Error); ok {
				r.Response.WriteJsonExit(RegisterRes{
					Code:  1,
					Error: v.FirstString(),
				})
			}
			// Other error.
			r.Response.WriteJsonExit(RegisterRes{
				Code:  1,
				Error: err.Error(),
			})
		}
		// ...
		r.Response.WriteJsonExit(RegisterRes{
			Data: req,
		})
	})
	s.SetPort(8199)
	s.Run()
}

执行后,我们通过curl工具提交数据来测试一下:

  1. JSON数据格式

    $ curl -d '{"username":"johngcn","password1":"123456","password2":"123456"}' "http://127.0.0.1:8199/register"
    {"code":0,"error":"","data":{"Name":"johngcn","Pass":"123456","Pass2":"123456"}}
    
    
    $ curl -d '{"username":"johngcn","password1":"123456","password2":"1234567"}' "http://127.0.0.1:8199/register"
    {"code":1,"error":"两次密码不一致","data":null}

    可以看到,我们提交的JSON内容也被Parse方法智能地转换为了结构体对象。

  2. XML数据格式

    $ curl -d '<?xml version="1.0" encoding="UTF-8"?><doc><username>johngcn</username><password1>123456</password1><password2>123456</password2></doc>' "http://127.0.0.1:8199/register"
    {"code":0,"error":"","data":{"Name":"johngcn","Pass":"123456","Pass2":"123456"}}
    
    
    $ curl -d '<?xml version="1.0" encoding="UTF-8"?><doc><username>johngcn</username><password1>123456</password1><password2>1234567</password2></doc>' "http://127.0.0.1:8199/register"
    {"code":1,"error":"两次密码不一致","data":null}

    可以看到,我们提交的XML内容也被Parse方法智能地转换为了结构体对象。

Content Menu



  • No labels

7 Comments

  1. 我这测试到一个bug,请看视频!

    链接: https://pan.baidu.com/s/129wXP_aRkLHMwNP4Uu07Gg  密码: l1c0
    --来自百度网盘超级会员V4的分享

    代码是示例2,测试指令如下:

    curl -d '{"username":"johngcn","password1":"123456","password2":"1323456"}' "http://127.0.0.1:8199/register"

    我将该指令重复执行数次就会发生有时候返回正确结果:

    {"code":1,"error":"两次密码不一致","data":null}

    有时候报错:

    Internal Error: runtime error: slice bounds out of range [:65] with capacity 0%

    %
    这是什么鬼???!!!

  2. 如果客户端提前的是json格式的数组,那么应该用哪个方法来处理啊?比如[{"username":"johngcn","password1":"123456","password2":"1323456"},{"username":"johng6677cn","password1":"123456","password2":"1323777456"}]

    1. type UserInfo struct {
      	UserName string `json:"user_name"`
      	Password string `json:"password"`
      }
      
      type UserRequest struct {
      	UserInfo *UserInfo `json:"user_info"`
      }
      var req *UserRequest
      if err := r.Parse(&req);err != nil{
      	
      }



  3. type Params struct {
    	Name string `json:"name"`
    	Pass string `json:"pass"`
    }

    s.BindHandler("/listUsers2", func(r *ghttp.Request) {
        var req *Params
        if err := r.Parse(&req); err != nil {
           fmt.Println(err)
         }
        fmt.Println(req)
    })

    curl -d '{"name":"john","pass":"123"}' http://127.0.0.1:8199/listUsers2

    获取不到json数据是什么原因
    1. 请检查自己的代码哈,我这把你代码测试了下没问题的。

      1. 我测试了,是curl的问题,不用curl是正常的,我也不知道如何设置CURL


        1. jun

          能说说你后面用什么测试的,我也获取不到