【发布时间】:2017-02-03 17:11:06
【问题描述】:
我正在使用 Protobuf 对象进行序列化,因为我们需要从 Java、CSharp 和 Python 客户端连接到 Java Web 服务。
如果我将 Java protobuf 字节写入文件,我只需执行以下操作就可以在 Python 中读取:
f = open("../../../../resources/test.protoBytes", "rb")
java_deserialized = timeSeriesRequests.TimeSeriesRequestMetaData()
java_deserialized.ParseFromString(f.read())
如果我从 Python 写入文件:
temp = time_series_request_meta_data.SerializeToString()
f = open("../../../../resources/test.protoBytes", "wb")
f.write(temp)
f.close()
如果在 Java 中阅读没有问题。
使用 suds-jurko 0.6 我尝试调用一个 SOAP 服务,该服务在 Java 中使用 byte[]:
client = Client('http://localhost:5750/ws/protoservice?wsdl', plugins=[LogPlugin()])
response = client.service.addValueToTimeSeries(data.SerializeToString(), otherData.SerializeToString())
服务器端方法签名:
public byte[] addValueToTimeSeries(byte[] protoRequestMetaData, byte[] protoRequest)
我可以在服务端调用下断点,方法被调用,但是字节数组字符串不正确。
这是从客户端发送的:
b'<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns0="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://services.common.ddp/"><SOAP-ENV:Header/><ns0:Body><ns1:addValueToTimeSeries><arg0>b'\\n\\x06ddp_sm\\x12\\x0btest-domain\\x1a\\tlocalhost'</arg0><arg1>b'\\n\\x06\\x08\\x81\\x9c\\x92\\xa5\\x05\\x12\\x06\\x08\\x81\\x9c\\x92\\xa5\\x05\\x1a\\x04Test"\\x05Test2*<\\n/type.googleapis.com/google.protobuf.DoubleValue\\x12\\t\\t\\x00\\x00\\x00\\x00\\x00\\x00Y@'</arg1></ns1:addValueToTimeSeries></ns0:Body></SOAP-ENV:Envelope>'
我尝试这样做:
response = client.service.addValueToTimeSeries(list(data.SerializeToString()), list(otherData.SerializeToString())
我可以看到在客户端创建了正确的字节数组,但现在在服务器端字节数组是空的。
这是从 Python 客户端发送的(来自登录 suds):
b'<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns0="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://services.common.ddp/"><SOAP-ENV:Header/><ns0:Body><ns1:addValueToTimeSeries><arg0>10</arg0><arg0>6</arg0><arg0>100</arg0><arg0>100</arg0><arg0>112</arg0><arg0>95</arg0><arg0>115</arg0><arg0>109</arg0><arg0>18</arg0><arg0>11</arg0><arg0>116</arg0><arg0>101</arg0><arg0>115</arg0><arg0>116</arg0><arg0>45</arg0><arg0>100</arg0><arg0>111</arg0><arg0>109</arg0><arg0>97</arg0><arg0>105</arg0><arg0>110</arg0><arg0>26</arg0><arg0>9</arg0><arg0>108</arg0><arg0>111</arg0><arg0>99</arg0><arg0>97</arg0><arg0>108</arg0><arg0>104</arg0><arg0>111</arg0><arg0>115</arg0><arg0>116</arg0><arg1>10</arg1><arg1>6</arg1><arg1>8</arg1><arg1>129</arg1><arg1>156</arg1><arg1>146</arg1><arg1>165</arg1><arg1>5</arg1><arg1>18</arg1><arg1>6</arg1><arg1>8</arg1><arg1>129</arg1><arg1>156</arg1><arg1>146</arg1><arg1>165</arg1><arg1>5</arg1><arg1>26</arg1><arg1>4</arg1><arg1>84</arg1><arg1>101</arg1><arg1>115</arg1><arg1>116</arg1><arg1>34</arg1><arg1>5</arg1><arg1>84</arg1><arg1>101</arg1><arg1>115</arg1><arg1>116</arg1><arg1>50</arg1><arg1>42</arg1><arg1>60</arg1><arg1>10</arg1><arg1>47</arg1><arg1>116</arg1><arg1>121</arg1><arg1>112</arg1><arg1>101</arg1><arg1>46</arg1><arg1>103</arg1><arg1>111</arg1><arg1>111</arg1><arg1>103</arg1><arg1>108</arg1><arg1>101</arg1><arg1>97</arg1><arg1>112</arg1><arg1>105</arg1><arg1>115</arg1><arg1>46</arg1><arg1>99</arg1><arg1>111</arg1><arg1>109</arg1><arg1>47</arg1><arg1>103</arg1><arg1>111</arg1><arg1>111</arg1><arg1>103</arg1><arg1>108</arg1><arg1>101</arg1><arg1>46</arg1><arg1>112</arg1><arg1>114</arg1><arg1>111</arg1><arg1>116</arg1><arg1>111</arg1><arg1>98</arg1><arg1>117</arg1><arg1>102</arg1><arg1>46</arg1><arg1>68</arg1><arg1>111</arg1><arg1>117</arg1><arg1>98</arg1><arg1>108</arg1><arg1>101</arg1><arg1>86</arg1><arg1>97</arg1><arg1>108</arg1><arg1>117</arg1><arg1>101</arg1><arg1>18</arg1><arg1>9</arg1><arg1>9</arg1><arg1>0</arg1><arg1>0</arg1><arg1>0</arg1><arg1>0</arg1><arg1>0</arg1><arg1>0</arg1><arg1>89</arg1><arg1>64</arg1></ns1:addValueToTimeSeries></ns0:Body></SOAP-ENV:Envelope>'
有人可以建议我需要做什么吗?
仅供参考,这是我的第一个 Python 应用程序,因此如果答案是微不足道的,我不会感到惊讶。对我来说,这似乎很奇怪,如果通过文件完成,但在通过 Web 服务完成时会失败。
我现在制作了一个小示例 web 服务,但无法上传 zip 它出现。
我尝试过像这样使用 struct.unpack:
struct.unpack('B' * len(serialized_request), serialized_request)
这会返回正确的 int 数组,但会作为空数组传递给 Web 服务。
下面是wsdl的内容:
<definitions targetNamespace="http://examples.com/" name="com.examples.ExampleWebService"><types><xsd:schema><xsd:import namespace="http://examples.com/" schemaLocation="http://localhost:5750/ws/examplewebservice?xsd=1"/></xsd:schema></types><message name="addRequest"><part name="parameters" element="tns:addRequest"/></message><message name="addRequestResponse"><part name="parameters" element="tns:addRequestResponse"/></message><portType name="ExampleWebServiceContract"><operation name="addRequest"><input wsam:Action="http://examples.com/ExampleWebServiceContract/addRequestRequest" message="tns:addRequest"/><output wsam:Action="http://examples.com/ExampleWebServiceContract/addRequestResponse" message="tns:addRequestResponse"/></operation></portType><binding name="ExampleWebServicePortBinding" type="tns:ExampleWebServiceContract"><soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/><operation name="addRequest"><soap:operation soapAction=""/><input><soap:body use="literal"/></input><output><soap:body use="literal"/></output></operation></binding><service name="com.examples.ExampleWebService"><port name="ExampleWebServicePort" binding="tns:ExampleWebServicePortBinding"><soap:address location="http://localhost:5750/ws/examplewebservice"/></port></service></definitions>
【问题讨论】:
-
我从未使用过 Java 编程,但根据我使用 Python 的经验 - SOAP 对 *** 来说是一种痛苦。如果没有 WSDL,将很难告诉您从 Python 端调用服务的方式有什么问题。
-
data是什么类型?也许SerializeToString是问题所在?看起来那里正在进行一些不必要的编码。 -
V Stoykov - 我现在为我创建的示例 Web 服务添加了 wsdl 的内容。
-
Haken Lid - SerializeToString 是从 [developers.google.com/protocol-buffers/docs/pythontutorial] 获取字节数组的推荐方式。它在读取/读取文件时有效,但在使用 Web 服务时无效。我尝试使用 struct.unpack('B' * len(serialized_request), serialized_request),它在客户端提供正确的字节数组,但在服务器端提供空字节数组,即与使用 list(meta_request.SerializeToString ())
标签: python python-3.x protocol-buffers suds