Django-WebService с soaplib xml-символами или амперсандом scaping?
Ну, это мой вопрос fisrt здесь, так что я постараюсь сделать это как можно лучше.
Я пытаюсь реализовать сервер WebService в Python 2.6 и Django 1.4 с Soaplib 2.0.
Веб-сервис работает, и Django обслуживает его нормально на сервере разработки Django.
Вот код для представления Django и URL:
Views.py
from soaplib.core.service import rpc, DefinitionBase, soap
from soaplib.core.model.primitive import String, Integer, Boolean
from soaplib.core.model.clazz import Array
from soaplib.core import Application
from soaplib.core.server.wsgi import Application as WSGIApplication
from django.http import HttpResponse
class HelloWorldService(DefinitionBase):
@soap(String,Integer,_returns=Array(String))
def say_smello(self,name,times):
results = []
for i in range(0,times):
results.append('Hello, %s'%name)
return results
@soap(String,_returns=Boolean)
def xml(self,xml):
result = xml
return True
@soap(String,_returns=String)
def xml2(self,xml2):
return xml2
class DjangoSoapApp(WSGIApplication):
csrf_exempt = True
def __init__(self, services, tns):
"""Create Django view for given SOAP soaplib services and
tns"""
return super(DjangoSoapApp,
self).__init__(Application(services, tns))
def __call__(self, request):
django_response = HttpResponse()
def start_response(status, headers):
django_response.status_code = int(status.split(' ', 1)[0])
for header, value in headers:
django_response[header] = value
response = super(DjangoSoapApp, self).__call__(request.META,
start_response)
django_response.content = 'n'.join(response)
return django_response
my_soap_service = DjangoSoapApp([HelloWorldService], __name__)
Urls.py
url(r'^soap/wsdl$', 'soap.views.my_soap_service'),
url(r'^soap/$', 'soap.views.my_soap_service'),
Дело в том, что я хочу перейти на веб-сервис метод xml или xml2 A XML и делать вещи с информацией, которая приходит в XML. Я получаю ошибки.
Если я передаю простую строку без символов, таких как"&", все работает нормально, например:
Сначала импортируем suds и устанавливаем suds для отладки:
from suds.client import Client
import logging
logging.basicConfig(level=logging.INFO)
logging.getLogger('suds.client').setLevel(logging.DEBUG)
А теперь давайте начнем вызывать de WS:
WSDL = "http://server.test/soap/wsdl"
client = Client(WSDL)
client.service.xml('x and y')
Работает отлично, я получаю "True", и журналы SUDS показывают мне, что делает это:
DEBUG:suds.client:sending to (http://server.test/soap/wsdl)
message:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:ns0="soap.views" xmlns:ns1="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<ns1:Body>
<ns0:xml>
<ns0:xml>x and y</ns0:xml>
</ns0:xml>
</ns1:Body>
</SOAP-ENV:Envelope>
DEBUG:suds.client:headers = {'SOAPAction': '"xml"', 'Content-Type': 'text/xml; charset=utf-8'}
DEBUG:suds.client:http succeeded:
<?xml version='1.0' encoding='utf-8'?>
<senv:Envelope xmlns:wsa="http://schemas.xmlsoap.org/ws/2003/03/addressing" xmlns:plink="http://schemas.xmlsoap.org/ws/2003/05/partner-link/" xmlns:xop="http://www.w3.org/2004/08/xop/include" xmlns:senc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:s0="soap.views" xmlns:s12env="http://www.w3.org/2003/05/soap-envelope/" xmlns:s12enc="http://www.w3.org/2003/05/soap-encoding/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:senv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"><senv:Body><s0:xmlResponse><s0:xml Result>true</s0:xmlResult></s0:xmlResponse></senv:Body></senv:Envelope>
True
Но если я это сделаю:
client.service.xml('x & y')
Не работает, он заканчивается пеной таймаут и сервер сообщают о сломанной трубе, это то, что журнал suds говорит мне толкает:
DEBUG:suds.client:sending to (http://server.test/soap/wsdl)
message:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:ns0="soap.views" xmlns:ns1="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<ns1:Body>
<ns0:xml>
<ns0:xml>x & y</ns0:xml>
</ns0:xml>
</ns1:Body>
</SOAP-ENV:Envelope>
DEBUG:suds.client:headers = {'SOAPAction': '"xml"', 'Content-Type': 'text/xml; charset=utf-8'}
И это ошибка на пене:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.6/site-packages/suds/client.py", line 542, in __call__
return client.invoke(args, kwargs)
File "/usr/lib/python2.6/site-packages/suds/client.py", line 602, in invoke
result = self.send(soapenv)
File "/usr/lib/python2.6/site-packages/suds/client.py", line 643, in send
reply = transport.send(request)
File "/usr/lib/python2.6/site-packages/suds/transport/https.py", line 64, in send
return HttpTransport.send(self, request)
File "/usr/lib/python2.6/site-packages/suds/transport/http.py", line 77, in send
fp = self.u2open(u2request)
File "/usr/lib/python2.6/site-packages/suds/transport/http.py", line 118, in u2open
return url.open(u2request, timeout=tm)
File "/usr/lib/python2.6/urllib2.py", line 391, in open
response = self._open(req, data)
File "/usr/lib/python2.6/urllib2.py", line 409, in _open
'_open', req)
File "/usr/lib/python2.6/urllib2.py", line 369, in _call_chain
result = func(*args)
File "/usr/lib/python2.6/urllib2.py", line 1190, in http_open
return self.do_open(httplib.HTTPConnection, req)
File "/usr/lib/python2.6/urllib2.py", line 1165, in do_open
raise URLError(err)
urllib2.URLError: <urlopen error timed out>
Благодаря этой ссылке: http://grokbase.com/p/python/soap/125nhj9bdm/python-suds-xml-encoding-issue я обнаруживаю, что да, если я размещаю веб-сервис что-то вроде:
client.service.xml("x &amp; y")
Я правильно понял:
DEBUG:suds.client:sending to (http://server.test/soap/wsdl)
message:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:ns0="soap.views" xmlns:ns1="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<ns1:Body>
<ns0:xml>
<ns0:xml>x &amp; y</ns0:xml>
</ns0:xml>
</ns1:Body>
</SOAP-ENV:Envelope>
DEBUG:suds.client:headers = {'SOAPAction': '"xml"', 'Content-Type': 'text/xml; charset=utf-8'}
True
Если я использую метод xml2, чтобы увидеть, что возвращает веб-сервис, это:
client.service.xml2("x &amp; y")
И журналы для пены:
DEBUG:suds.client:sending to (http://server.test/soap/wsdl)
message:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:ns0="soap.views" xmlns:ns1="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<ns1:Body>
<ns0:xml2>
<ns0:xml2>x &amp; y</ns0:xml2>
</ns0:xml2>
</ns1:Body>
</SOAP-ENV:Envelope>
DEBUG:suds.client:headers = {'SOAPAction': '"xml2"', 'Content-Type': 'text/xml; charset=utf-8'}
DEBUG:suds.client:http succeeded:
<?xml version='1.0' encoding='utf-8'?>
<senv:Envelope xmlns:wsa="http://schemas.xmlsoap.org/ws/2003/03/addressing" xmlns:plink="http://schemas.xmlsoap.org/ws/2003/05/partner-link/" xmlns:xop="http://www.w3.org/2004/08/xop/include" xmlns:senc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:s0="soap.views" xmlns:s12env="http://www.w3.org/2003/05/soap-envelope/" xmlns:s12enc="http://www.w3.org/2003/05/soap-encoding/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:senv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"><senv:Body><s0:xml2Response><s0:xml2Result>x & y</s0:xml2Result></s0:xml2Response></senv:Body></senv:Envelope>
x & y
Но я не думаю, что проблема в SUDS, потому что я использую эту версию suds, чтобы протолкнуть XML в java WebServices, но я не нашел способ этого soaplib.
Есть Идеи? Это сводит меня с ума xD
Моя конечная цель состоит в том, чтобы иметь веб-сервис с Soaplib и толкать XML к нему от soap-клиента на Java.
Спасибо
1 ответ:
ОК, решено: D
Я мог только изменить серверную часть, поэтому я переношу свой код в spyne и работает как заклинание.
Https://github.com/arskom/spyne
Я нашел это в их сети:
Из soaplib они отправились в Rpclib, а оттуда в Spyne.Soaplib-2.0 was never released as a stable package, but the branch is still available
Верно, что я нашел новую ошибку, на этот раз на suds, но suds я просто использовал для тестирования, но если я использую другие клиенты, SoapUI или Java clientes, работает отлично.
После установки его с помощью PIP, это код Джанго:
Urls.py
url(r'^testws/\?wsdl$', 'testmo.views.ws_test'), url(r'^testws/$', 'testmo.views.ws_test'),
Views.py
from django.views.decorators.csrf import csrf_exempt from spyne.server.django import DjangoApplication from spyne.model.primitive import String from spyne.service import ServiceBase from spyne.interface.wsdl import