通过多个marshallings保留json.RawMessage

问题描述 投票:2回答:1

Background

我正在使用必须是non-repudiable的JSON数据。

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

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

Issue

我似乎无法保留原始的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接口,但我看起来错了。

Things I've Tried

我的下一次尝试是尝试:

// 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个回答
0
投票

您将需要一个带有自己的封送程序的自定义类型,而不是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
}
© www.soinside.com 2019 - 2024. All rights reserved.