3

当内容类型为“application/json”时,Revel 不解析 JSON 参数。

如何执行?

例子 :

http://localhost:9000/foundations在 POST 调用Foundations.Create函数中。进入我fmt.Println("Params :", c.Params)用来检查参数的这个函数

Ruby POST JSON 数据

#!/usr/bin/env ruby
require "rubygems"
require "json"
require "net/https"

uri = URI.parse("http://localhost:9000/foundations")
http = Net::HTTP.new(uri.host, uri.port)

header = { "Content-Type" => "application/json" }

req = Net::HTTP::Post.new(uri.path, header)
req.body = { 
  "data" => "mysurface"
}.to_json()

res = http.start { |http| http.request(req) }

调试打印是 Params : &{map[] map[] map[] map[] map[] map[] []}

当我不使用“应用程序/json”时: curl -F 'data=mysurface' http://127.0.0.1:9000/foundations

打印是: Params : &{map[data:[mysurface]] map[] map[] map[] map[data:[mysurface]] map[] []}

4

1 回答 1

2

问题在于,对于 json,Revel 无法像处理“正常”发布请求一样真正处理它。通常,它可以将每个参数绑定到一个map[string]string对象中。但是对于 JSON,它必须能够处理数组和嵌套对象,如果事先不知道 JSON 的结构是什么,就没有很好的方法来做到这一点。

所以解决方案是自己处理它 - 你应该知道期望什么字段,所以struct用这些字段创建一个,然后json.Unmarshal进入它。

import (
    "encoding/json"
    "fmt"
)

type Surface struct {
    Data string `json:"data"` //since we have to export the field
                              //but want the lowercase letter
}

func (c MyController) Action() revel.Result {
    var s Surface
    err := json.Unmarshal([]byte(c.Request.Body), &s)    
    fmt.Println(s.Data) //mysurface
}

如果您不喜欢使用json:"data"标签或不想导出您的字段,您也可以编写自己的UnmarshalJSON函数

type Surface struct {
    data string `json:"data"` //can use unexported field
                              //since we handle JSON ourselves
}

func (s *Structure) UnmarshalJSON(data []byte) error {
    if (s == nil) {
        return errors.New("Structure: UnmarshalJSON on nil pointer")
    }
    var fields map[string]string
    json.Unmarshal(data, &fields)    
    *s.data = fields["data"]
    return nil
}
于 2014-10-29T17:02:42.910 回答