18

I have a struct containing strings as []byte fields which I'd like to encode into JSON. However, the generated JSON contains a non expected string representation of the slice contents. Here is an example of what I refer:

package main

import (
    "fmt"
    "encoding/json"
    )

type Msg struct {
    Content []byte
}

func main() {
    helloStr := "Hello"
    helloSlc := []byte(helloStr)
    fmt.Println(helloStr, helloSlc)

    obj := Msg{helloSlc}
    json, _ := json.Marshal(obj)
    fmt.Println(string(json))
}

This produces the following output:

Hello [72 101 108 108 111]
{"Content":"SGVsbG8="}

What kind of conversion is the json.Marshal() method performing to the []byte encoded string. How can I generate a JSON with the original content of my string {"Content":"Hello"}?

prl900
  • 3,741
  • 3
  • 31
  • 40

2 Answers2

18

A []byte is marshalled as base64 encoded string. From the documentation:

Array and slice values encode as JSON arrays, except that []byte encodes as a base64-encoded string, and a nil slice encodes as the null JSON object.

These values are decoded properly when unmarshalled.

The reason why this is done is that JSON does not have a native representation for raw bytes. See this question for a detailed explanation.

Community
  • 1
  • 1
nemo
  • 51,795
  • 12
  • 128
  • 131
  • So, I guess the only way of properly formatting my JSON would be to cast the []byte into a string before encoding it. Or is there a better approach to this problem? – prl900 Apr 07 '16 at 01:35
  • 3
    Your JSON is properly formatted. This behaviour is not a bug and intended. If you want a string representation and are dealing with text only, use `string` instead of `[]byte`. – nemo Apr 07 '16 at 01:38
5

I came a cross the same thing and even if this is a rather old question and already answered there is another option.

If you use json.RawMessage (which internaly is a []byte) as a type instead of []byte the Marshaling works into a Json String as expected.

silverfighter
  • 6,562
  • 10
  • 42
  • 71
  • Do note that the resulting byte slice will differ from the JSON value because it will be wrapped in double quotes, i.e it contains 2 extra `"` symbols on each end of the slice – tutuDajuju Feb 06 '20 at 16:42