【问题标题】:Preserve json.RawMessage through multiple marshallings通过多个编组保留 json.RawMessage
【发布时间】:2018-01-01 20:15:44
【问题描述】:

背景

我正在处理必须为 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 接口,但我似乎弄错了。

我尝试过的事情

我的下一个尝试是尝试:

// 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!

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

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

【问题讨论】:

标签: json go


【解决方案1】:

您将需要一个带有自己的封送拆收器的自定义类型来代替 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
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-15
    • 2012-09-10
    • 2019-05-11
    • 2020-11-26
    • 1970-01-01
    • 2012-09-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多