0

我正在尝试与一个 RESTful API 交互,该 API 在帖子中接受 application/x-protobuf 对象。

.proto 示例对象:

message register
{
    required string name = 1;
    required int32 id = 2;
}

使用请求我可以将此消息发布到服务器并收到 200。

例如

register = protobuf_pb2.register()
register.name = "foo"
register.id = 1

response = requests.request("POST", url, data=register.SerializeToString(), headers=headers)

当我以 SerializeToString() 格式查看此有效负载时,它显示类似于

b'\n\t\n\x03foo\x10\x01'

作为健全性检查,然后我可以创建一个新的消息对象和 .ParseFromString() 将其恢复为正确的消息格式。

服务器上的第二个 uri 允许您发送 GET 请求来检索相同的数据。所以我使用了以下内容:

register = protobuf_pb2.register()
response = requests.request("GET", url, headers=headers).content
register.ParseFromString(response)

响应返回

b'foo:1\n'

ParseFromString 返回异常

DecodeError('解析消息错误',)

我在某处错过了一步吗?.content 有效载荷是否应该在解析之前以某种方式编码?

非常感谢。

4

1 回答 1

0

您从服务器返回的对象是二进制数据,UTF-8 编码,因此 Python 将其解释为一个bytes对象(在 Python 3 中,bytes并且str是不同的类型)。

m = b'foo:1\n'
type(m)
Out[1]: bytes

m.decode('utf-8')
Out[2]: 'foo:1\n'

ParseFromString然而需要一个字符串,所以它抛出一个DecodeError; 只需使用decode()适当的编码。

在响应标头中,您应该能够找到使用的编码:几乎每个人都使用 UTF-8,但在“真实”生产代码中,您也应该检查:在Content-Type(或者您甚至可以请求特定的Accept-Charset但您如果服务器无法满足它,可能会得到 406)。

于 2019-04-17T04:52:08.327 回答