Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 years ago.
Improve this question
I have a very simple http resonse in my server where i json encode a struct. But its sending a blank of just {}
I don't know if i am doing it wrong but i get no errors. This is my json encode:
// Set uuid as string to user struct
user := User{uuid: uuid.String()}
fmt.Println(user) // check it has the uuid
responseWriter.Header().Set("Content-Type", "application/json")
responseWriter.WriteHeader(http.StatusCreated)
json.NewEncoder(responseWriter).Encode(user)
On the recieving end the data has:
Content-Type application/json
Content-Length 3
STATUS HTTP/1.1 201 Created
{}
Why does it not give me the uuid data? Am i doing something wrong with my encoding?
Export the field name by making the first character of the identifier's name a Unicode upper case letter (Unicode class "Lu").
Try this:
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
)
type User struct {
Uuid string
}
func handler(responseWriter http.ResponseWriter, r *http.Request) {
user := User{Uuid: "id1234657..."} // Set uuid as string to user struct
fmt.Println(user) // check it has the uuid
responseWriter.Header().Set("Content-Type", "application/json")
responseWriter.WriteHeader(http.StatusCreated)
json.NewEncoder(responseWriter).Encode(user)
}
func main() {
http.HandleFunc("/", handler) // set router
err := http.ListenAndServe(":9090", nil) // set listen port
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
output(http://localhost:9090/):
{"Uuid":"id1234657..."}
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 months ago.
Improve this question
https://go.dev/play/p/L2IJp-ehA2S
The following program provides me the required output (ccc09e). But this is correct approach or this can be improved.
package main
import (
"encoding/json"
"fmt"
)
type People struct {
Name string
}
func main() {
empJson := `[{"name":"ccc09e"}]`
var emp []People
json.Unmarshal([]byte(empJson), &emp)
s := fmt.Sprintf("%v", emp[0])
s = s[1 : len(s)-1]
fmt.Println(s)
}
I got the required output https://go.dev/play/p/L2IJp-ehA2S and I need improvement to the program.
Looks like you want the Name of the First element of People array in s
No need to do string manipulations. Just access it directly
package main
import (
"encoding/json"
"fmt"
)
type People struct {
Name string
}
func main() {
empJson := `[{"name":"ccc09e"}]`
var emp []People
json.Unmarshal([]byte(empJson), &emp)
s := emp[0].Name
fmt.Println(s)
}
https://go.dev/play/p/O2hiGuSyM53
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
I need to parse a JSON into Go struct. Following is the struct
type Replacement struct {
Find string `json:"find"`
ReplaceWith string `json:"replaceWith"`
}
Following is an example json:
{
"find":"TestValue",
"replaceWith":""
}
The input json can have empty values for some field. Go's encoding/json library by default takes nil value for any empty string provided in JSON.
I've a downstream service, which finds and replaces the replaceWith values in configurations. This is causing issues with my downstream service as it doesn't accept nil for the replaceWith parameter. I have a workaround where I'm replacing nil values by "''" but this can cause an issue where some value is replaced with ''. Is there a way for json to not parse empty string as nil and just ""
Here is a link to the code: https://play.golang.org/p/SprPz7mnWR6
In Go string type cannot hold nil value which is zero value for pointers, interfaces, maps, slices, channels and function types, representing an uninitialized value.
When unmarshalling JSON data to struct as you do in your example ReplaceWith field will indeed be an empty string ("") - which is exactly what you are asking for.
type Replacement struct {
Find string `json:"find"`
ReplaceWith string `json:"replaceWith"`
}
func main() {
data := []byte(`
{
"find":"TestValue",
"replaceWith":""
}`)
var marshaledData Replacement
err := json.Unmarshal(data, &marshaledData)
if err != nil {
fmt.Println(err)
}
if marshaledData.ReplaceWith == "" {
fmt.Println("ReplaceWith equals to an empty string")
}
}
You can use Pointer in string and if the value is missing in JSON then it would be nil. I have done the same in past but currently I don't have code with me.
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
I'm currently trying to serialize some string slice in a CSV without saving output to a file. I saw some examples using bytes.Buffer but even my the smallest test doesn't work. I don't know how to debug this, the code compiles without warning and doesn't throw error after writer.Flush(). It also works correctly with saving result to a file or piping it directly to standard output
Any help would be appreciated :)
Thx.
PS: the final print is just a test. I know i can use csv.NewWriter(os.stdout) to do so (and it works) but it doesn't fit my needs. I really would like to get the result in a byte array.
package main
import (
"bytes"
"encoding/csv"
"fmt"
)
func main() {
var buffer bytes.Buffer
writer := csv.NewWriter(&buffer)
writer.Write([]string{"1", "2", "3", "4"})
writer.Write([]string{"5", "6", "7", "8"})
defer writer.Flush()
if err := writer.Error(); err != nil {
panic(err)
}
fmt.Println(buffer.Bytes())
}
You are deferring the Flush call, making it execute after the fmt.Println call. Call Flush immediately:
package main
import (
"bytes"
"encoding/csv"
"fmt"
)
func main() {
var buffer bytes.Buffer
writer := csv.NewWriter(&buffer)
writer.Write([]string{"1", "2", "3", "4"})
writer.Write([]string{"5", "6", "7", "8"})
writer.Flush()
if err := writer.Error(); err != nil {
panic(err)
}
fmt.Println(buffer.String())
}
https://play.golang.org/p/BHTyfsuf0tY
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 years ago.
Improve this question
I try to write a function, the code:
package main
import (
"encoding/json"
"fmt"
)
type Test struct {
Data map[string]interface{} `json:"data"`
}
func main() {
jsonStr := "{\"data\": {\"id\": 999804707614896129}}"
t := &Test{}
json.Unmarshal([]byte(jsonStr), t)
fmt.Println(int64(t.Data["id"].(float64)))
var x float64 = 999804707614896129
fmt.Println(int64(x))
}
The result is below:
999804707614896128
999804707614896128
Why the results are 999804707614896128, not 999804707614896129.
Because 999804707614896129 cannot be represented exactly with a value of type float64. float64 uses the IEEE 754 standard for representing floating point numbers. It's a format with limited precision (roughly 16 decimal digits).
If you need to "transfer" the exact number, use string and not JSON number. If the number "fits" into an int64, you will be able to parse it "exactly" (else just work with it as a string or use big.Int):
jsonStr := `{"data": {"id": "999804707614896129"}}`
t := &Test{}
if err := json.Unmarshal([]byte(jsonStr), t); err != nil {
panic(err)
}
s := t.Data["id"].(string)
fmt.Println(s)
var x int64
x, err := strconv.ParseInt(s, 10, 64)
fmt.Println(x, err)
This will output (try it on the Go Playground):
999804707614896129
999804707614896129 <nil>
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.