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

+3


source to share


1 answer


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
}

      

+2


source







All Articles