2017-02-03 3 views
0

Я использую объекты Protobuf для сериализации, поскольку нам необходимо подключиться от клиентов Java, CSharp и Python к веб-службе Java.Проблема, выполняющая веб-сервис Java с Python с использованием suds и protobuf с параметрами байтового массива

Если я пишу 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.

Использование пенообразования-Jurko 0,6 попытка вызова службы SOAP, который принимает байты [] в Java, выполнив:

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) 

я могу положить перерыв point на вызове на стороне сервера, и вызывается метод, но строка массива байтов неверна.

Это был послан от клиента:

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\\[email protected]&apos;</arg1></ns1:addValueToTimeSeries></ns0:Body></SOAP-ENV:Envelope>' 

Я пытался делать это вместо:

response = client.service.addValueToTimeSeries(list(data.SerializeToString()), list(otherData.SerializeToString()) 

и я могу видеть, что в клиенте создается правильный массив, но теперь на серверный массив байтов пуст.

Это передается от клиента Python (от входа в пене):

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>' 

Может кто-то пожалуйста, предложить то, что мне нужно сделать?

FYI, это мое первое приложение на Python, поэтому я не удивлюсь, если ответ будет тривиален. Мне кажется очень странным, что это работает, если это делается с помощью файлов, но не выполняется, когда выполняется через веб-службу.

Я сейчас сделал небольшой пример веб-службы, но не могу загрузить ZIP-код.

Я попытался с помощью struct.unpack так:

struct.unpack('B' * len(serialized_request), serialized_request) 

Это возвращает правильный массив Int, но передается через веб-службы, как пустой массив.

Ниже содержимое 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> 
+0

Я никогда не программировался на Java, но из моего опыта работы с Python - SOAP - это боль в ***. Без WSDL будет сложно рассказать вам, в чем проблема с тем, как вы вызываете службу со стороны Python. –

+0

Какой тип 'data'? Может быть, проблема 'SerializeToString'? Похоже, есть некоторая ненужная кодировка. –

+0

В. Стойков. Я добавил содержимое wsdl для примера веб-сервиса, который я создал. – Chill

ответ

0

Перепробовав множество комбинаций, я обнаружил, что передать массив в пене из Python, используя Protobuf вам нужно сделать следующие шаги:

  1. Вызов SerializeToString() на объекте Protobuf
  2. Передайте строковое представление байтов в base64.b64encode (т.е.import base64 module)
  3. Вызов декодирования() на результат, который возвращает ASCII, отбрасывая b 'в начале и' в конце.