dongzouxigu12345 2014-10-29 04:29
浏览 74
已采纳

在Revel(Golang)中自动解析参数JSON

Revel doesn't parse JSON parameter when the content type is "application/json".

How to enforce this ?

Example :

http://localhost:9000/foundations in POST call Foundations.Create function. Into this function I use fmt.Println("Params :", c.Params) to check parameters

Ruby POST JSON data

#!/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) }

The debug print is Params : &{map[] map[] map[] map[] map[] map[] []}

And when I use none "application/json" like : curl -F 'data=mysurface' http://127.0.0.1:9000/foundations

The print is : Params : &{map[data:[mysurface]] map[] map[] map[] map[data:[mysurface]] map[] []}

  • 写回答

1条回答 默认 最新

  • dpd3447 2014-10-29 17:02
    关注

    The issue is that with json, there is no way for Revel to really handle it in the same way it does with a "normal" post request. Normally, it can just bind each param into an map[string]string object. But with JSON, it has to be able to handle arrays and nested objects, and there is no good way of doing that without knowing beforehand what the structure of the JSON will be.

    So the solution, is to handle it yourself - you should know what fields to expect, so create a struct with those fields, and json.Unmarshal into it.

    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
    }
    

    If you don't like using the json:"data" tag or don't want to export your field, you could also write your own UnmarshalJSON function

    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
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 支付宝h5参数如何实现跳转
  • ¥15 MATLAB代码补全插值
  • ¥15 Typegoose 中如何使用 arrayFilters 筛选并更新深度嵌套的子文档数组信息
  • ¥15 前后端分离的学习疑问?
  • ¥15 stata实证代码答疑
  • ¥50 husky+jaco2实现在gazebo与rviz中联合仿真
  • ¥15 dpabi预处理报错:Error using y_ExtractROISignal (line 251)
  • ¥15 在虚拟机中配置flume,无法将slave1节点的文件采集到master节点中
  • ¥15 husky+kinova jaco2 仿真
  • ¥15 zigbee终端设备入网失败