Automatic JSON parsing option in Reval (Golang)
Revel does not parse the JSON parameter when the content type is "application / json".
How can this be ensured?
Example:
http://localhost:9000/foundations
in the POST call function Foundations.Create
. In this function I use fmt.Println("Params :", c.Params)
to check the 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) }
Debug Print
Params : &{map[] map[] map[] map[] map[] map[] []}
And when I am not using "application / json" for example:
curl -F 'data=mysurface' http://127.0.0.1:9000/foundations
Printing:
Params : &{map[data:[mysurface]] map[] map[] map[] map[data:[mysurface]] map[] []}
source to share
The problem is that with json for Revel, there is no way to handle this in the same way as with a normal post request. Typically, it can just bind each parameter to an object map[string]string
. But with JSON it must be able to handle arrays and nested objects, and there is no good way to do this without knowing in advance what the JSON structure will be.
So the solution is to handle it yourself - you have to know what fields to expect, so create struct
with those fields and json.Unmarshal
in 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 tag json:"data"
or you don't want to export your field, you can also write your own functionUnmarshalJSON
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
}
source to share