一尘不染

如何阻止json.Marshal转义<和>?

go

package main

import "fmt"
import "encoding/json"

type Track struct {
    XmlRequest string `json:"xmlRequest"`
}

func main() {
    message := new(Track)
    message.XmlRequest = "<car><mirror>XML</mirror></car>"
    fmt.Println("Before Marshal", message)
    messageJSON, _ := json.Marshal(message)
    fmt.Println("After marshal", string(messageJSON))
}

是否有可能做出json.Marshal无法逃脱<>?我目前得到:

{"xmlRequest":"\u003ccar\u003e\u003cmirror\u003eXML\u003c/mirror\u003e\u003c/car\u003e"}

但我正在寻找这样的事情:

{"xmlRequest":"<car><mirror>XML</mirror></car>"}

阅读 308

收藏
2020-07-02

共1个答案

一尘不染

从Go 1.7开始,您仍然 无法使用json.Marshal()做到​​这一点
json.Marshal源代码显示:

> err := e.marshal(v, encOpts{escapeHTML: true})

json.Marshal总是这样做的原因是:

字符串值编码为强制转换为有效UTF-8的JSON字符串,用Unicode替换符文替换无效字节。尖括号“ <”和“>”转义为“ \ u003c”和“ \
u003e”,以防止某些浏览器将JSON输出误解为HTML。由于相同的原因,“&”号也转义为“ \ u0026”。

这意味着您甚至无法通过编写自定义来做到这一点func (t *Track) MarshalJSON(),您必须使用不满足json.Marshaler接口的功能。

因此,解决方法是编写您自己的函数:

func (t *Track) JSON() ([]byte, error) {
    buffer := &bytes.Buffer{}
    encoder := json.NewEncoder(buffer)
    encoder.SetEscapeHTML(false)
    err := encoder.Encode(t)
    return buffer.Bytes(), err
}

https://play.golang.org/p/FAH-XS-QMC

如果您想要任何结构的通用解决方案,则可以执行以下操作:

func JSONMarshal(t interface{}) ([]byte, error) {
    buffer := &bytes.Buffer{}
    encoder := json.NewEncoder(buffer)
    encoder.SetEscapeHTML(false)
    err := encoder.Encode(t)
    return buffer.Bytes(), err
}

https://play.golang.org/p/bdqv3TUGr3

2020-07-02