Why golang didn't marshal the json object? [duplicate] - json

This question already has answers here:
json.Marshal(struct) returns "{}"
(3 answers)
Closed 5 years ago.
I wonder why the following didn't marshall to json successfully? I am trying to use a very simple example to learn json package.
package main
import (
"encoding/json"
"fmt"
)
type Message struct {
username string `json:"name"`
message string `json:"message"`
}
func main() {
var m = Message{
username: "hello",
message: "world",
}
js, _ := json.Marshal(m)
fmt.Println(m)
fmt.Println(string(js))
}

username
message
start with a lowercase letter, meaning they are unexported (think private), and so are not visible to the encoding/json package. You need to export your fields, or implement the MarshalJSON() ([]byte, error) method and do it yourself.

Related

Parsing Json to Struct in Go doesn't work [duplicate]

This question already has answers here:
json.Marshal(struct) returns "{}"
(3 answers)
(un)marshalling json golang not working
(3 answers)
Printing Empty Json as a result [duplicate]
(1 answer)
json.Unmarshal json string to object is empty result [duplicate]
(1 answer)
json.Unmarshal not returning decoded data [duplicate]
(1 answer)
Closed 11 months ago.
I runned the bellow code to retrieve a json from api and parse the values to a struct to use the values, but the print appears in blank.
The json format is:
"user":{
"id":13,
"name":"xpto",
"email":"bla#blum.com.br",
"role":"partner"
},
"token":"hjhfsdhfjkhskfjhsjkfhjksdhfjkshfkjsoiwwsnskcnksjcjkscksjcksbsdsdjsdj"
}
and the code that i am running is:
package main
import (
"bytes"
"encoding/json"
"io/ioutil"
"net/http"
)
type resposta struct {
usuario usuario `json:"user"`
token string `json:"token"`
}
type usuario struct {
id string `json:"id"`
name string `json:"name"`
email string `json:"email"`
role string `json:"role"`
}
func main() {
values := map[string]string{"email": "blablum#xpto.com.br", "password": "senhaaaaa"}
jsonValue, _ := json.Marshal(values)
response, _ := http.Post("https://api.endereco.com.br/sessions", "application/json", bytes.NewBuffer(jsonValue))
defer response.Body.Close()
body, _ := ioutil.ReadAll(response.Body)
println(body)
println(string(body))
var result resposta
json.Unmarshal(body, &result)
println("Resposta")
println(result.token)
println(result.token)
}
Any suggestion?
All your struct fields are unexported (they begin with a lowercase letter) and thus are considered "private." This is preventing the json package from seeing them with reflection. Export your fields by naming them with a Capital letter and it'll work.
Here's an example with some test data: https://go.dev/play/p/0lWdLtNuOr3

How to convert escaped json into a struct [duplicate]

This question already has answers here:
decode json including json encoded strings
(1 answer)
Unmarshaling a stringified json
(1 answer)
Closed 1 year ago.
I am having trouble converting an escaped json object into a struct.
The main problem I am facing is the escaped json for the sources field.
The following data is how it's being saved.
{
"key": "123",
"sources": "{\"1a\":\"source1a\",\"2b\":\"source2b\",\"3c\":\"source3c\",\"default\":\"sourcex\"}"
}
type config struct {
Key string `json:"key" validate:"required"`
Sources ???? `json:"sources" validate:"required"`
}
I then will have a source value and would like to check if my value is found in the json.
If my value is "1a" return "source1a", etc.
I'm trying to write this in a unit test as well.
Some might do a custom unmarshal method, but I think it's easier just to do two passes:
package main
import (
"encoding/json"
"fmt"
)
const s = `
{
"key": "123",
"sources": "{\"1a\":\"source1a\",\"2b\":\"source2b\",\"3c\":\"source3c\",\"default\":\"sourcex\"}"
}
`
func main() {
var t struct{Key, Sources string}
json.Unmarshal([]byte(s), &t)
m := make(map[string]string)
json.Unmarshal([]byte(t.Sources), &m)
fmt.Println(m) // map[1a:source1a 2b:source2b 3c:source3c default:sourcex]
}

how to unmarshal simple json with lowercase member into a struct [duplicate]

This question already has an answer here:
Why struct fields are showing empty?
(1 answer)
Closed 2 years ago.
I have a simple struct with string and int.
When I unmarshal a json the struct members are not getting parsed if beginning with lowercase string .Even if I am using in the same package
package main
import (
"encoding/json"
"fmt"
)
type Bird struct {
Species string
Description string
lifespan int
}
func main() {
birdJson := `{"species": "pigeon","description": "likes to perch on rocks","lifespan": 9}`
var bird Bird
json.Unmarshal([]byte(birdJson), &bird)
fmt.Printf("Species: %s, Description: %s,lifespan: %d", bird.Species, bird.Description,bird.lifespan)
//Cant read the lifespan ??
}
lifespan int
needs to be
Lifespan int
you can't unmarshal into an unexported field

Why is Go json.Marshal rejecting these struct tags? What is proper syntax for json tags? [duplicate]

This question already has an answer here:
Can't unmarshall JSON with key names having spaces
(1 answer)
Closed 4 years ago.
I am trying to use json.Marshal but it refuses to accept my struct tags.
What am I doing wrong?
Here is the source code for "marshal.go"
https://play.golang.org/p/eFe03_89Ly9
package main
import (
"encoding/json"
"fmt"
)
type Person struct {
Name string `json: "name"`
Age int `json: "age"`
}
func main() {
p := Person{Name: "Alice", Age: 29}
bytes, _ := json.Marshal(p)
fmt.Println("JSON = ", string(bytes))
}
I get these error messages from "go vet marshal.go"
./marshal.go:9: struct field tag `json: "name"` not compatible with reflect.StructTag.Get: bad syntax for struct tag value
./marshal.go:10: struct field tag `json: "age"` not compatible with reflect.StructTag.Get: bad syntax for struct tag value
I get this output when I run the program.
% ./marshal
JSON = {"Name":"Alice","Age":29}
Notice the field names match the Go structure and ignore the json tags.
What am I missing?
Oh my goodness! I just figured it out. There is no space allowed between json: and the field name "name".
The "go vet" error message ("bad syntax") is remarkably unhelpful.
The following code works. Can you see the difference?
package main
import (
"encoding/json"
"fmt"
)
type Person struct {
Name string `json:"name"`
Age int `json:"age"`
}
func main() {
p := Person{Name: "Alice", Age: 29}
bytes, _ := json.Marshal(p)
fmt.Println("JSON = ", string(bytes))
}

Making HTTP responses with JSON [duplicate]

This question already has an answer here:
json.Unmarshal returning blank structure
(1 answer)
Closed 3 years ago.
I am new to Go, and I am trying to practice with building a simple HTTP server. However I met some problems with JSON responses. I wrote following code, then try postman to send some JSON data. However, my postman always gets an empty response and the content-type is text/plain; charset=utf-8. Then I checked a sample in http://www.alexedwards.net/blog/golang-response-snippets#json. I copied and pasted the sample, and it was working well. But I cannot see any difference between mine and the sample. Can someone give some help?
package main
import (
"encoding/json"
"net/http"
)
type ResponseCommands struct {
key string
value bool
}
func main() {
http.HandleFunc("/", handler)
http.ListenAndServe(":5432", nil)
}
func handler(rw http.ResponseWriter, req *http.Request) {
responseBody := ResponseCommands{"BackOff", false}
data, err := json.Marshal(responseBody)
if err != nil {
http.Error(rw, err.Error(), http.StatusInternalServerError)
return
}
rw.WriteHeader(200)
rw.Header().Set("Content-Type", "application/json")
rw.Write(data)
}
The main difference is that the variable in the struct are public (exported)
type Profile struct {
Name string
Hobbies []string
}
In your case, they are not (lowercase).
type ResponseCommands struct {
key string
value bool
}
See "Lowercase JSON key names with JSON Marshal in Go".
As VonC already answered correct. Just want to add that IDEA can help with such 'small' problems.
I'm using Gogland and it let me know that json tag cannot be applied to lowercase field.