Golang json decoding returns empty [duplicate] - json

This question already has answers here:
JSON and dealing with unexported fields
(2 answers)
Closed 4 years ago.
Can some one please explain to me why this code fail to decode json properly:
package main
import (
"fmt"
"os"
"log"
"encoding/json"
)
type Config struct {
mongoConnectionString string `json:"database"`
Elastic struct{
main string `json:"main"`
log string `json:"log"`
} `json:"elastic"`
logFilePath string `json:"logfile"`
}
func main(){
loadConfiguration("./config.json")
}
func loadConfiguration(file string){
var configuration Config
configFile, err := os.Open(file); if err != nil {
log.Panic("Could not open", file)
}
defer configFile.Close()
if err := json.NewDecoder(configFile).Decode(&configuration); err != nil {
log.Panic("./config.json is currupted")
}
fmt.Print(configuration.logFilePath)
}
Json data:
{
"database": "localhost",
"elastic": {
"main": "test",
"log": "test"
},
"logfile": "./logs/log.log"
}
The execution of this program will result in empty configuration.logFilePath
What am i missing?
Thanks

For the json package to properly decode from json in go, fields must be exported (capitalized) within the struct definition.
Changing Config to:
type Config struct {
MongoConnectionString string `json:"database"`
Elastic struct{
Main string `json:"main"`
Log string `json:"log"`
} `json:"elastic"`
LogFilePath string `json:"logfile"`
}
will make all fields deserialize correctly.

Related

Can not parse json file in go [duplicate]

This question already has answers here:
json.Unmarshal returning blank structure
(1 answer)
Making HTTP responses with JSON [duplicate]
(2 answers)
Closed 3 years ago.
I'm trying to parse a json file using GoLang but it seems like not work. Am I doing right?
this is my Go Code:
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
)
type info struct {
username string `json:"username"`
password string `json:"password"`
timedelay int `json:"timedelay"`
courselist []string `json:"courselist"`
}
func main() {
var jsonParse info
file, err := ioutil.ReadFile("info.json")
if err != nil {
fmt.Println(err)
}
fmt.Println("My file content is:\n", string(file))
fmt.Println("---------------Parsing Json File----------------")
json.Unmarshal(file, &jsonParse)
fmt.Println("My Json Parse is:\n", jsonParse)
}
and this is my json file
{
"username" : "17020726",
"password": "Blueflower",
"timedelay": 200,
"courselist": ["54"]
}
this is result of my code
My file content is:
{
"username" : "17020726",
"password": "Blueflower",
"timedelay": 200,
"courselist": ["54"]
}
---------------Parsing Json File----------------
My Json Parse is:
{ 0 []}
The info struct fields are private. Capitalize the first letters.

Has Json tag but not exported [duplicate]

This question already has answers here:
JSON and dealing with unexported fields
(2 answers)
(un)marshalling json golang not working
(3 answers)
Closed 4 years ago.
Begining to study golang.
Task: Get Json and Unmarshall it.
But I get mistake:
Json tag but not exported
How to make unexported fields become exported and then implement it using methods?
Here is the code:
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
type Time struct {
time
}
type time struct {
id string `json:"$id"`
currentDateTime string `json:"currentDateTime,string"`
utcOffset float64 `json:"utcOffset,string"`
isDayLightSavingsTime bool `json:"isDayLightSavingsTime,string"`
dayOfTheWeek string `json:"dayOfTheWeek,string"`
timeZoneName string `json:"timeZoneName,string"`
currentFileTime float64 `json:"currentFileTime,string"`
ordinalDate string `json:"ordinalDate,string"`
serviceResponse string `json:"serviceResponse,string"`
}
func (t *Time) GetTime() (Time, error) {
result := Time{}
return result, t.Timenow(result)
}
func (t *Time) Timenow(result interface{}) error {
res, err := http.Get("http://worldclockapi.com/api/json/utc/now")
if err != nil {
fmt.Println("Cannot get Json", err)
}
body, err := ioutil.ReadAll(res.Body)
if err != nil {
fmt.Println("Cannot create Body", err)
}
defer res.Body.Close()
var resultJson interface{}
return json.Unmarshal(body, &resultJson)
}
func main() {
var a Time
t, err := a.GetTime()
if err != nil {
fmt.Println("Error ", err)
}
fmt.Println("Time:", t)
}
Please explain in details whats wrong with struct and how to get right response?
You're adding a JSON tag to a field that isn't exported.
Struct fields must start with upper case letter (exported) for the JSON package to see their value.
struct A struct {
// Unexported struct fields are invisible to the JSON package.
// Export a field by starting it with an uppercase letter.
unexported string
// {"Exported": ""}
Exported string
// {"custom_name": ""}
CustomName string `json:"custom_name"`
}
The underlying reason for this requirement is that the JSON package uses reflect to inspect struct fields. Since reflect doesn't allow access to unexported struct fields, the JSON package can't see their value.

getting Blank values while reading from JSON file in GoLang [duplicate]

This question already has an answer here:
Printing Empty Json as a result [duplicate]
(1 answer)
Closed 6 years ago.
I am trying to learn Go. I am writing a simple program to get values from JSON file in GoLang.
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
)
type bands struct {
id string `json:"id"`
name string `json:"name"`
location string `json:"location"`
year string `json:"year"`
}
func main() {
bands := getBands()
fmt.Println(bands)
}
func getBands() []bands {
raw, err := ioutil.ReadFile("../data/bands.json")
if err != nil {
fmt.Println(err.Error())
os.Exit(1)
}
var c []bands
json.Unmarshal(raw, &c)
return c
}
Also, below is my JSON File:
[{"id":"1","name": "The Beatles","location": "NY","year": "2012"},
{"id":"2","name": "Nirvana","location": "NY","year": "2010"},
{"id":"3","name": "Metallica","location": "NY","year": "1980"}]
When i am running the file, I am getting blank values.
Thanks for the help.
The fields must start with uppercase letters.
type bands struct {
Id string `json:"id"`
Name string `json:"name"`
Location string `json:"location"`
Year string `json:"year"`
}

Error with JSON parsing in Golang

I develop this code:
package main
import (
"fmt"
"io/ioutil"
"encoding/json"
)
type Client struct{
host string
key string
secrete string
username string
password string
}
type Config struct{
Client []Client
}
func main(){
content, err := ioutil.ReadFile("conf2.json")
if err!=nil{
fmt.Print("Error:",err)
}
var conf Config
err=json.Unmarshal(content, &conf)
if err!=nil{
fmt.Print("Error:",err)
}
json.Unmarshal(content, &conf)
fmt.Println(conf.Client[0].host)
}
to parse and print the first host detail from my json, that looks like this:
{
"Client" :
[
{"host":"192.168.1.2"},
{"key":"abcdf"},
{"secrete":"9F6w"},
{"username":"user"},
{"password":"password"}
]
}
But I got an empty string. Could someone know the reason?
Three things to fix:
json.Unmarshal requires the struct fields to be capitalized to be exported or they are ignored
You need the json:"<name>" specifier after the fields so the unmarshal knows the struct field to json mapping
Your json was making multiple clients with one field filled in instead of one client with all the fields filled in
See example: https://play.golang.org/p/oY7SppWNDC
Here, it is the solution to my problem:
package main
import (
"fmt"
"io/ioutil"
"encoding/json"
)
type Client struct {
Host string `json:"host"`
Key string `json:"apikey"`
Secret string `json:"secret"`
Username string `json:"username"`
Password string `json:"password"`
}
type Config struct {
Client Client `json:"Client"`
}
func main(){
jsonmsg, err := ioutil.ReadFile("conf2.json")
conf := new(Config)
err = json.Unmarshal([]byte(jsonmsg), &conf)
if err != nil {
fmt.Print("Error:", err)
}
fmt.Printf("%+v\n%+v\n%+v\n%+v\n%+v\n", conf.Client.Host, conf.Client.Key, conf.Client.Secret, conf.Client.Username,conf.Client.Password)
}

(un)marshalling json golang not working

I'm playing with Go and am stumped as to why json encode and decode don't work for me
I think i copied the examples almost verbatim, but the output says both marshal and unmarshal return no data. They also don't give an error.
can anyone hint to where i'm going wrong?
my sample code: Go playground
package main
import "fmt"
import "encoding/json"
type testStruct struct {
clip string `json:"clip"`
}
func main() {
//unmarshal test
var testJson = "{\"clip\":\"test\"}"
var t testStruct
var jsonData = []byte(testJson)
err := json.Unmarshal(jsonData, &t)
if err != nil {
fmt.Printf("There was an error decoding the json. err = %s", err)
return
}
fmt.Printf("contents of decoded json is: %#v\r\n", t)
//marshal test
t.clip = "test2"
data, err := json.Marshal(&t)
if err != nil {
fmt.Printf("There was an error encoding the json. err = %s", err)
return
}
fmt.Printf("encoded json = %s\r\n", string(data))
}
output:
contents of decoded json is: main.testStruct{clip:""}
encoded json = {}
in both outputs I would have expected to see the decoded or encoded json
For example,
package main
import "fmt"
import "encoding/json"
type testStruct struct {
Clip string `json:"clip"`
}
func main() {
//unmarshal test
var testJson = "{\"clip\":\"test\"}"
var t testStruct
var jsonData = []byte(testJson)
err := json.Unmarshal(jsonData, &t)
if err != nil {
fmt.Printf("There was an error decoding the json. err = %s", err)
return
}
fmt.Printf("contents of decoded json is: %#v\r\n", t)
//marshal test
t.Clip = "test2"
data, err := json.Marshal(&t)
if err != nil {
fmt.Printf("There was an error encoding the json. err = %s", err)
return
}
fmt.Printf("encoded json = %s\r\n", string(data))
}
Output:
contents of decoded json is: main.testStruct{Clip:"test"}
encoded json = {"clip":"test2"}
Playground:
http://play.golang.org/p/3XaVougMTE
Export the struct fields.
type testStruct struct {
Clip string `json:"clip"`
}
Exported identifiers
An identifier may be exported to permit access to it from another
package. An identifier is exported if both:
the first character of the identifier's name is a Unicode upper case letter (Unicode class "Lu"); and
the identifier is declared in the package block or it is a field name or method name.
All other identifiers are not exported.
Capitalize names of structure fields
type testStruct struct {
clip string `json:"clip"` // Wrong. Lowercase - other packages can't access it
}
Change to:
type testStruct struct {
Clip string `json:"clip"`
}
In my case, my struct fields were capitalized but I was still getting the same error.
Then I noticed that the casing of my fields was different. I had to use underscores in my request.
For eg:
My request body was:
{
"method": "register",
"userInfo": {
"fullname": "Karan",
"email": "email#email.com",
"password": "random"
}
}
But my golang struct was:
type AuthRequest struct {
Method string `json:"method,omitempty"`
UserInfo UserInfo `json:"user_info,omitempty"`
}
I solved this by modifying my request body to:
{
"method": "register",
"user_info": {
"fullname": "Karan",
"email": "email#email.com",
"password": "random"
}
}