在Go中将JSON[]字节封送为字符串



我有一个结构,它包含作为[]字节字段的字符串,我想将其编码到JSON中。但是,生成的JSON包含切片内容的非预期字符串表示。以下是我所指的一个例子:

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))
}

这会产生以下输出:

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

json是什么样的转换。对[]字节编码的字符串执行的Marshal()方法。如何使用字符串{"content":"Hello"}的原始内容生成JSON?

[]byte被编组为base64编码的字符串。来自文件:

数组和切片值编码为JSON数组,除了[]byte编码为base64编码的字符串,nil切片编码为null JSON对象。

这些值在解组时会正确解码。

这样做的原因是JSON没有原始字节的本机表示。有关详细解释,请参阅此问题。

我遇到了同样的问题,即使这是一个相当古老的问题,并且已经回答了,还有另一个选择。

如果使用json.RawMessage(内部是[]字节)作为类型而不是[]byte,则编组将按预期工作到Json字符串中。

您可以使用第三方库来实现您想要的

package main
import (
    "fmt"
    "strconv"
    "strings"
    "time"
    "unsafe"
    jsoniter "github.com/json-iterator/go"
)
func main() {
    err := test()
    if err != nil {
        panic(err)
    }
}
func test() error {
    jsoniter.RegisterTypeEncoder("[]uint8", &uint8Enc{})
    var a struct {
        A []byte `json:"a"`
        B []byte `json:"b"`
    }
    a.A = []byte{'1', 1, 2, 3, '9'}
    a.B = []byte(time.Now().String())
    s, err := json.MarshalIndent(a, "", "  ")
    if err != nil {
        return err
    }
    fmt.Println(string(s))
    return nil
}
var json = jsoniter.ConfigCompatibleWithStandardLibrary
type uint8Enc struct{}
func (ue *uint8Enc) IsEmpty(ptr unsafe.Pointer) bool {
    data := *((*[]uint8)(ptr))
    return len(data) == 0
}
func (ue *uint8Enc) Encode(ptr unsafe.Pointer, stream *jsoniter.Stream) {
    var (
        data = *((*[]uint8)(ptr))
        sb   strings.Builder
    )
    const hexTable = "0123456789abcdef"
    for _, v := range data {
        if strconv.IsPrint(rune(v)) {
            sb.WriteByte(v)
        } else {
            sb.WriteString(`x`)
            sb.WriteByte(hexTable[v>>4])
            sb.WriteByte(hexTable[v&0x0f])
        }
    }
    stream.WriteString(sb.String())
}

结果如下

{
  "a": "1\x01\x02\x039",
  "b": "2023-06-05 09:15:38.551518 +0800 CST m=+0.003193401"
}

最新更新