【问题标题】:Issue executing Java web service from Python using suds and protobuf with byte array parameters使用带有字节数组参数的 suds 和 protobuf 从 Python 执行 Java Web 服务的问题
【发布时间】: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&apos;\\n\\x06ddp_sm\\x12\\x0btest-domain\\x1a\\tlocalhost&apos;</arg0><arg1>b&apos;\\n\\x06\\x08\\x81\\x9c\\x92\\xa5\\x05\\x12\\x06\\x08\\x81\\x9c\\x92\\xa5\\x05\\x1a\\x04Test&quot;\\x05Test2*&lt;\\n/type.googleapis.com/google.protobuf.DoubleValue\\x12\\t\\t\\x00\\x00\\x00\\x00\\x00\\x00Y@&apos;</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


【解决方案1】:

在尝试了很多组合之后,我发现要使用 Protobuf 从 Python 将字节数组传递给 suds,您需要执行以下步骤:

  1. 在 Protobuf 对象上调用 SerializeToString()
  2. 将字节的字符串表示形式传递给base64.b64encode(即导入base64模块)
  3. 对结果调用 decode(),返回 ASCII,剥离开头的 b' 和结尾的 '。

【讨论】:

    猜你喜欢
    • 2011-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-14
    • 2016-09-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多