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 2024-五一综合模拟赛
  • ¥15 下图接收小电路,谁知道原理
  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度
  • ¥30 关于#r语言#的问题:如何对R语言中mfgarch包中构建的garch-midas模型进行样本内长期波动率预测和样本外长期波动率预测
  • ¥15 ETLCloud 处理json多层级问题
  • ¥15 matlab中使用gurobi时报错
  • ¥15 这个主板怎么能扩出一两个sata口
  • ¥15 不是,这到底错哪儿了😭