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[] []}
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
}