简体   繁体   English

Django - 带有soaplib xml字符或&符号的WebService?

[英]Django - WebService with soaplib xml characters or ampersand scaping?

Well this is my fisrt Question here so I'll try to do it the best I can. 那么这是我的fisrt问题,所以我会尽力做到最好。

I am trying to implement a WebService server in Python 2.6 and Django 1.4 with Soaplib 2.0. 我正在尝试使用Soaplib 2.0在Python 2.6和Django 1.4中实现WebService服务器。

The Webservice is working and Django is serving it ok in the Django development server. Web服务正在运行,Django在Django开发服务器中正常运行。

Here is the code for the Django View and Urls: 这是Django View和Urls的代码:

views.py 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 urls.py

url(r'^soap/wsdl$', 'soap.views.my_soap_service'),
url(r'^soap/$', 'soap.views.my_soap_service'),

The thing is, I want to pass to the WebService method xml or xml2 a XML and the do stuff with the info that comes in the XML. 问题是,我想传递给WebService方法xml或xml2一个XML,并使用XML中的信息来做东西。 I get errors. 我收到错误。

If I pass a simple string without characters like “&” everything works fine, for example: 如果我传递一个没有像“&”这样的字符的简单字符串,一切正常,例如:

First let's import suds and set suds to Debug: 首先让我们导入suds并设置suds到Debug:

from suds.client import Client
import logging
logging.basicConfig(level=logging.INFO)
logging.getLogger('suds.client').setLevel(logging.DEBUG)

And now lets start calling de WS: 现在让我们开始调用de WS:

WSDL = "http://server.test/soap/wsdl"
client = Client(WSDL)
client.service.xml('x and y')

works perfect, I get “True” and the logs of SUDS show me is doing this: 工作完美,我得到“真实”,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

But if I do: 但如果我这样做:

client.service.xml('x &  y')

is not working, it ends with a suds timeout and the server report a broken pipe, this is what the suds log tells me is pushing: 没有工作,它以suds超时结束,服务器报告一个损坏的管道,这是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 &amp;  y</ns0:xml>
      </ns0:xml>
   </ns1:Body>
</SOAP-ENV:Envelope>
DEBUG:suds.client:headers = {'SOAPAction': '"xml"', 'Content-Type': 'text/xml; charset=utf-8'}

And this is the error on suds: 这是suds的错误:

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>

Thanks to this link: http://grokbase.com/p/python/soap/125nhj9bdm/python-suds-xml-encoding-issue I discover that yes, if I post the WebService something like: 感谢这个链接: http//grokbase.com/p/python/soap/125nhj9bdm/python-suds-xml-encoding-issue我发现是的,如果我发布WebService类似于:

client.service.xml("x &amp;amp; y")

I get it right: 我做对了:

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

If I use the method xml2 so I can see what returns the WebService is this: 如果我使用方法xml2所以我可以看到返回WebService的是:

client.service.xml2("x &amp;amp; y")

And the logs for Suds: 和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:xml2>
         <ns0:xml2>x &amp;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 &amp; y</s0:xml2Result></s0:xml2Response></senv:Body></senv:Envelope>
x & y

but I don't think the problem is in SUDS, because I use this version of suds to push XML to java WebServices, but I haven't find a way this soaplib. 但我不认为问题出在SUDS中,因为我使用这个版本的suds将XML推送到java WebServices,但我还没有找到这种soaplib的方法。

Any Ideas? 有任何想法吗? This is driving me a bit crazy xD 这让我有点疯狂xD

My Final goal is to have the Webservice with Soaplib and push a XML to it from a soap client in Java. 我的最终目标是让Webservice与Soaplib一起使用Java从SOAP客户端推送XML。

Thanks 谢谢

Ok, solved :D 好的,解决了:D

I could only change the server side, so I migrate my code to spyne and works like a Charm. 我只能更改服务器端,因此我将代码迁移到spyne并像Charm一样工作。

https://github.com/arskom/spyne https://github.com/arskom/spyne

I found this on their web: 我在他们的网站上发现了这个:

 Soaplib-2.0 was never released as a stable package, but the branch is still available

From soaplib they went to Rpclib and from there to Spyne. 从soaplib他们去了Rpclib并从那里到Spyne。

Is true that I found a new bug, this time on suds, but suds I just used for testing, but if I use other clients, SoapUI or Java clientes, works perfect. 确实,我发现了一个新的错误,这次是在suds上,但是我刚用于测试的泡沫,但如果我使用其他客户端,SoapUI或Java客户端,则工作完美。

After Installing it with PIP, this is the Django code: 用PIP安装后,这是Django代码:

urls.py urls.py

url(r'^testws/\?wsdl$', 'testmo.views.ws_test'),
url(r'^testws/$', 'testmo.views.ws_test'),

views.py 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 Wsdl11
from spyne.protocol.soap import Soap11
from spyne.application import Application
from spyne.decorator import srpc



class ServiceWsTest(ServiceBase):
    @srpc(String, _returns=String)
    def testMethod(string):
        return string

ws_test = csrf_exempt(DjangoApplication(Application([ServiceWsTest],
    'http://example.com',
    in_protocol=Soap11(),
    out_protocol=Soap11(),
    interface=Wsdl11(),
)))

From now on, I'll keep working with this library 从现在开始,我将继续使用这个库

Maybe you can wrap it, unescaped, in a cdata tag. 也许你可以用cdata标签包装它,未转义。 More info at http://en.wikipedia.org/wiki/CDATA 有关更多信息,请访问http://en.wikipedia.org/wiki/CDATA

<![CDATA[
x & y
]]>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM