Reputation: 13
Attempting to use a custom MarshalJSON
to avoid escaping characters like &
. It's inconvenient to use a custom encoder with the SetEscapeHTML
option set in this particular case.
The function is called, and behaves as I expected. However the end result still contains the escaped form \u0026
.
https://play.golang.org/p/aktPndOUmth
package main
import (
"bytes"
"encoding/json"
"fmt"
)
type Data struct {
URL string
}
func (d Data) MarshalJSON() ([]byte, error) {
data := map[string]interface{}{
"url": d.URL,
}
jsonData, _ := json.Marshal(data)
jsonData = bytes.Replace(jsonData, []byte("\\u0026"), []byte("&"), -1)
fmt.Println("func: " + string(jsonData))
return jsonData, nil
}
func main() {
data := Data{
URL: "https://test.com?foo=1&bar=2",
}
jsonData, _ := json.Marshal(data)
fmt.Println("main: " + string(jsonData))
}
Output:
func: {"url":"https://test.com?foo=1&bar=2"}
main: {"url":"https://test.com?foo=1\u0026bar=2"}
Upvotes: 1
Views: 4067
Reputation: 2222
This is how I unescape sequences to make non-English letters in JSON to be readable. It will work as well for special characters like <
, >
, and &
.
func _UnescapeUnicodeCharactersInJSON(_jsonRaw json.RawMessage) (json.RawMessage, error) {
str, err := strconv.Unquote(strings.Replace(strconv.Quote(string(_jsonRaw)), `\\u`, `\u`, -1))
if err != nil {
return nil, err
}
return []byte(str), nil
}
func main() {
// Both are valid JSON.
var jsonRawEscaped json.RawMessage // json raw with escaped unicode chars
var jsonRawUnescaped json.RawMessage // json raw with unescaped unicode chars
// '\u263a' == '☺'
jsonRawEscaped = []byte(`{"HelloWorld": "\uC548\uB155, \uC138\uC0C1(\u4E16\u4E0A). \u263a"}`) // "\\u263a"
jsonRawUnescaped, _ = _UnescapeUnicodeCharactersInJSON(jsonRawEscaped) // "☺"
fmt.Println(string(jsonRawEscaped)) // {"HelloWorld": "\uC548\uB155, \uC138\uC0C1(\u4E16\u4E0A). \u263a"}
fmt.Println(string(jsonRawUnescaped)) // {"HelloWorld": "안녕, 세상(世上). ☺"}
}
https://play.golang.org/p/pUsrzrrcDG-
Upvotes: 5