使用构造的soap报文与Webservice通信

背景:项目使用了 gSoap 来自动生成 Webservice, 在尝试了诸多 python 类库之后( suds, pysoap等),均无法与server端正确通信

正因如此,开始尝试自己构造 soap 报文来与 Webservice 通信。

WebService 暴露的接口如下:

  ControlDevice(xs:string deviceSerialNums, xs:string szCommandInfo, xs:string szCommandParam, xs:boolean bGroup, )
  ExportConfigs(xs:string deviceSerialNum, xs:string softServiceName, xs:string configName, )
  GetDeviceInfo(xs:string deviceSerialNums, xs:int nDeviceInfoType, xs:boolean bGroup, )
  GetHSCConfig(xs:string deviceSerialNum, xs:string softServiceName, xs:string configName, )
  GetSoftStatusInfo(xs:string deviceSerialNum, xs:string softServiceName, xs:string section, )
  GetUpgradeProgress(xs:string deviceSerialNums, xs:string packagePath, xs:boolean bGroup, )
  GetVersion()
  ImportConfigs(xs:string deviceSerialNums, xs:string configContent, )
  SetDeviceInfo(xs:string deviceSerialNum, xs:string newDeviceInfo, xs:boolean bGroup, )
  SetDeviceNetInfo(xs:string deviceSerialNums, xs:string netInfo, xs:boolean bGroup, )
  SetHSCConfigItem(xs:string deviceSerialNums, xs:string softServiceName, xs:string configName, xs:string newValues, )
  UpgradeSoftware(xs:string deviceSerialNums, xs:string packagePath, xs:boolean bGroup, )

将整个client 工程分为两部分,第一部分用于构造 soap报文与整个post请求;第二部分使用 httplib 收发构造的请求与WebService的返回

第一部分: envelope.py
<code>
# -- coding: utf-8 --
# @Author: riposa
# @Date: 2016-07-15 11:12:15
# @Last Modified by: riposa
# @Last Modified time: 2016-07-15 17:58:46
'''
module for constructing soap request and resolve soap post
'''

import xml.etree.cElementTree as ET
import json


class SoapEnvelopeTree(object):
    '''
        Soap Envelope Tree parser
    '''

    def __init__(self, envString):

        if not envString:
            # construct new envelope xml tree
            root = ET.Element('soapenv:Envelope')
            root.set('xmlns:soapenv', 'http://schemas.xmlsoap.org/soap/envelope/')
            ET.SubElement(root, 'soapenv:Body')
            self.root = root
            self.tree = ET.ElementTree(root)

        else:
            self.root = ET.fromstring(envString)

    def set_sub_element(self, father, tag, text=None, attrib=None):
        '''
            add sub element to the specific father tag
        '''

        father_el = [ i for i in self.root.iter(father)][0]
        if type(father_el) == None:
            return ('error', 'can not find the node')
        child = ET.SubElement(father_el, tag)
        if text:
            child.text = text
        if attrib:
            for i in attrib.keys():
                child.set(i, attrib[i])

        return 0

    def get_post_content(self):
        '''
            get the soap post content(json) by resolving xml string
        '''

        try:
            err_el = [ i for i in self.root.iter('SOAP-ENV:Fault')][0]
            return ('error', err_el.find('faultstring').text)
        except IndexError:
            a = [j for j in self.root.iter('result')][0]
            try:
                return ('success', json.loads(a.text))
            except ValueError:
                return ('success', a.text)


def soap_request(url, method, param=None):
    with open('header.conf') as head_file:
        head = json.loads(head_file.read().replace(r'%url%', url))

    env_tree = SoapEnvelopeTree(None)
    env_tree.set_sub_element('soapenv:Body', 'ns1:%s' % method, None,
                            {"xmlns:ns1":"http://tempuri.org/vtns.xsd"})
    if param:
        for i in param.keys():
            env_tree.set_sub_element('ns1:%s' % method, i, param[i], None)
    
    data = '<?xml version="1.0" encoding="UTF-8"?>' + ET.tostring(env_tree.root, encoding='utf-8')

    return (head, data)


def resolve_post(response):
    env_tree_post = SoapEnvelopeTree(response)
    (status, content) = env_tree_post.get_post_content()

    return content

</code>

第二部分: soap_client.py

<code>
# -- coding: utf-8 --
# @Author: riposa
# @Date: 2016-07-15 14:48:29
# @Last Modified by: riposa
# @Last Modified time: 2016-07-15 17:02:12
'''module for send and recv soap message'''

import httplib
import sys
reload(sys)
sys.setdefaultencoding('utf-8')

from envelope import soap_request, resolve_post

def call(url, port, method, param=None):
    (head, data) = soap_request(url, method, param)

    http_client = httplib.HTTPConnection(url, port, timeout=5)
    http_client.request('POST', '/', data, head)
    try:
        response = http_client.getresponse()
    except httplib.BadStatusLine:
        print 'illegal params cause no response'
    result = resolve_post(response.read())
    http_client.close()

    return result

</code>

调用方式:
soap_client.call(目标IP, 目标端口, 方法名, 参数(Optional))

基于项目约定, webservice返回值一律为 json, 因此 call() 返回值为解析后的soap content,类型为 dict(python)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,319评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,801评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,567评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,156评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,019评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,090评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,500评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,192评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,474评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,566评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,338评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,212评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,572评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,890评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,169评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,478评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,661评论 2 335

推荐阅读更多精彩内容