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

报告相同问题?

悬赏问题

  • ¥20 BAPI_PR_CHANGE how to add account assignment information for service line
  • ¥500 火焰左右视图、视差(基于双目相机)
  • ¥100 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染
  • ¥15 CVRP 图论 物流运输优化
  • ¥15 Tableau online 嵌入ppt失败
  • ¥100 支付宝网页转账系统不识别账号
  • ¥15 基于单片机的靶位控制系统
  • ¥15 真我手机蓝牙传输进度消息被关闭了,怎么打开?(关键词-消息通知)
  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?