json - 通过多个编码保留 json.RawMessage

标签 json go

背景

我正在处理必须为 non-repudiable 的 JSON 数据.

授予我这些数据的 API 也有一个服务来验证数据最初来自他们。

As best as I can tell ,他们通过要求他们最初发送的完整 JSON 需要在另一个 JSON 请求中提供给他们来做到这一点,没有字节更改。

问题

我似乎无法保留原始 JSON!

因为我无法修改原始的 JSON,所以我在解码时小心地将其保存为 json.RawMessage:

// struct I unmarshal my original data into 
type SignedResult struct {
    Raw           json.RawMessage `json:"random"`
    Signature     string          `json:"signature"`
    ...
}

// struct I marshal my data back into
type VerifiedSignatureReq {
    Raw          json.RawMessage  `json:"random"`
    Signature     string          `json:"signature"`
}

// ... getData is placeholder for function that gets my data
response := SignedResult{}
x, _ := json.Unmarshal(getData(), &response)

// do some post-processing with SignedResult that does not alter `Raw` or `Signature`

// trouble begins here - x.Raw started off as json.RawMessage...
y := json.Marshal(VerifiedSignatureReq{Raw: x.Raw, Signature: x.Signature}

// but now y.Raw is base64-encoded.

问题是 []bytes / RawMessages are base64-encoded when marshaled .所以我不能使用这个方法,因为它完全改变了字符串。

我不确定如何确保正确保留此字符串。我曾假设我的结构中的 json.RawMessage 规范会在编码一个已经编码的实例的危险中幸存下来,因为它实现了 Marshaler 接口(interface),但我似乎错了。

我尝试过的事情

我的下一次尝试是尝试:

// struct I unmarshal my original data into 
type SignedResult struct {
    Raw           json.RawMessage `json:"random"`
    Signature     string          `json:"signature"`
    ...
}

// struct I marshal my data back into
type VerifiedSignatureReq {
    Raw          map[string]interface{}  `json:"random"`
    Signature     string          `json:"signature"`
}

// ... getData is placeholder for function that gets my data
response := SignedResult{}
x, _ := json.Unmarshal(getData(), &response)

// do some post-processing with SignedResult that does not alter `Raw` or `Signature`

var object map[string]interface{}
json.Unmarshal(x.Raw, &object)
// now correctly generates the JSON structure.
y := json.Marshal(VerifiedSignatureReq{Raw: object, Signature: x.Signature}

// but now this is not the same JSON string as received!

这种方法的问题是数据之间的间距存在细微的字节差异。当 cat 到一个文件时,它看起来不再完全一样。

我也不能使用 string(x.Raw),因为它在使用 \ 编码时会转义某些字符。

最佳答案

您需要一个带有自己的编码(marshal)拆收器的自定义类型,以代替 json.RawMessage 供您的 VerifiedSignatureReq 结构使用。示例:

type VerifiedSignatureReq {
    Raw           RawMessage  `json:"random"`
    Signature     string      `json:"signature"`
}

type RawMessage []byte

func (m RawMessage) MarshalJSON() ([]byte, error) {
    return []byte(m), nil
}

关于json - 通过多个编码保留 json.RawMessage,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48052917/

相关文章:

go - map 查找失败时从模板返回解析错误

docker - 如何在子文件夹中使用 go.mod 构建 golang docker 镜像?

java - JSON服务器以生成JSON(用Java语言)

php - 如何制作一个 web 服务(最好使用 PHP),Android 应用程序可以请求它获取 JSON 对象

javascript - JavaScript中的Json响应未正确循环

go - 在Golang中附加文件并通过SMTP发送时没有正文的电子邮件

Go (golang) 中的 MongoDB 与 mgo : how to use logical operators to query?

go - 如何每秒重复函数N次?

json - 我如何处理 HTTP 加载失败(错误代码 : -1009 [1:50]) in swift 4?

mysql - MySQL Labs JSON native 类型:如何求和jsn_extract返回的数组的结果?