直接用Qt写soap

直接用Qt写soap

最近的项目里用到了webservice, 同事用的是`gSoap`来搞的.
用这个本身没什么问题, 但这货生成的代码实非人类可读, 到处都是`__`和`_`, 看得我眼晕.....
其实项目里用的webservice很简单, 暂时只有身份验证这一个, 所以就想能不能直接用Qt搞定.
说搞就搞, 哪知一下就搞了1天半.....
把过程记录下来, 以防我的老脑筋忘记了 -_____-!

原理

我们用的webservice是基于xml的, 也叫soap.
而soap = http + xml, 所以原理就很简单了:
     用QHttp直接连服务器, 将请求的内容以指定xml格式组织好后, POST到服务端就OK了
 
怎么样, 原理很简单吧, 但对于我这个从来没写过http请求的人来说, 还是出了不少的状况.
 
* 400 Bad Request
     这个问题一般都是post写错了, 应该是大写`POST`才行.
 
* 500 interval server error
     一开始一直都是400错误, 不停的改代码的过程中, 也出了几次500错误.
 
出现这个错误, 一般都是xml的格式有误导致的, 如我看网上写的会在xml的开头添加一个`\n`, 我也加了, 结果就是这种错误.
 
** 注意事项 **
 
webservice中, 至少有两个header是必须填写的:
 
1. Content-Type
2. Content-Length
 
因为内容是xml格式的文本, 所以这两个必须写, 否则服务器无法正确解析.
 
代码
试验的时候, 用的是PyQt4写的, 所以这里就贴点这个代码吧:
 
       import sys
       from PyQt4.QtGui import *
       from PyQt4.QtCore import *
       from PyQt4.QtNetwork import *

       class MainWindow(QMainWindow) :

           def __init__( self, parent = None) :
              QMainWindow. __init__( self, parent)
               self._http = None

               self.test()

           def test( self) :
              http = QHttp( '10.88.104.158')
               self._http = http

              data = '' '<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <UserLogin xmlns="http://www.richfit.com/">
      <userLoginName>admin</userLoginName>
      <userPwd>123</userPwd>
      <appType>test</appType>
    </UserLogin>
  </soap:Body>
</soap:Envelope>'
''

              req = QHttpRequestHeader()
              req.setRequest( 'POST', '/3DWebGIS/Services/DataService.asmx')
              req.setValue( 'Host', '10.88.104.158')
              req.setValue( 'Content-Type', 'text/xml; charset=utf-8')
              req.setValue( 'Content-Length', str( len(data)))
              req.setValue( 'SOAPAction', '"http://www.richfit.com/UserLogin"')

               self.connect( self._http, SIGNAL( 'requestFinished(int, bool)'), self.finish)

              cnt = data.encode( 'utf-8')
               print http.request(req, cnt)

           def test1( self) :

               import sys, httplib
              data = '' '<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <UserLogin xmlns="http://www.richfit.com/">
      <userLoginName>admin</userLoginName>
      <userPwd>123</userPwd>
      <appType>test</appType>
    </UserLogin>
  </soap:Body>
</soap:Envelope>'
''

              h = httplib.HTTP( '10.88.104.158')
              h.putrequest( 'POST', '/3DWebGIS/Services/DataService.asmx')
              h.putheader( 'Host', '10.88.104.158')
              h.putheader( 'User-Agent', 'Python post')
              h.putheader( 'Content-Type', 'text/xml; charset="UTF-8"')
              h.putheader( 'Content-length', str( len(data)))
              h.putheader( 'SOAPAction', '"http://www.richfit.com/UserLogin"')
              h.endheaders()
              h.send(data)

              sc, sm, header = h.getreply()
               print sc, sm
               print header
               print h.getfile().read()

           def finish( self, iid, ok) :
               print iid, ok
              resp = self._http.lastResponse()
               print resp.statusCode(), resp.reasonPhrase()
               print str( self._http.readAll()).decode( 'utf-8')

          app = QApplication( sys.argv)
          frm = MainWindow()
          frm.show()
          app.exec_()
 
这里其实提供了两种方式来实现soap请求的, 其中`test`是用qt的方案实现的, `test1`用的是最原始的方法实现的.
 
这里的东西在原理部分都可以对照上, 只有一点要注意一下:
 
      http = QHttp( '10.88.104.158')
      h = httplib.HTTP( '10.88.104.158')
 
这两句里的地址**不能**带`http://`哦!!
 
参考资料:
 

转载于:https://www.cnblogs.com/chaoswong/p/3412313.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值