WebService调用的开发记事(嘉讯软件)

阅读本文必备知识(Http协议),话说这个都不懂,你都不好意思说自己是码畜😓(真的不懂Http的,我向你推荐罗剑锋老师的【透视Http协议】)
对WebService的了解只需要有
1、WebService是基于Http的
2、WebService的头部的Content-Type就两种,即【text/soap+xml】或【text/xml】,且由于有报文体,所以必是POST请求

3、知道Xml是有命名空间这种东西,即一个元素的语法是<命名空间:元素名>,

3.1、命名空间需要定义后才能使用,定义必须在父级或当前元素的特性上写(就是元素名后打个空格写),格式为xmlns:命名空间名="值,类似一个地址"。
3.2、命名空间名字是随意的,不必参照本文的命名,你可以从简,比如soapenv,可以简写为s,比如上一篇的广州玄武科技就是如此,
3.3、不写命名空间时,会使用根元素的命名空间。

4、一般WebService都会有个返回说明文档的链接,形如:http://XXX?wsdl
5、Xml的大致格式:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tns="【TargetNameSpace】">
  <soapenv:Header/>
  <soapenv:Body>
    <tns:【方法名】>
      <【参数1>XXX</【参数1】>
      <【参数2>YYY</【参数2】>
    </tns:【方法名】>
  </soapenv:Body>
</soapenv:Envelope>

5.1、最外层的命名空间,即上面的soapenv的值是固定的,为http://schemas.xmlsoap.org/soap/envelope/

5.2、其中tns的是http://XXX?wsdl的返回那坨Xml里面的TargetNameSpapce的值,这里tns就是缩写,所有方法的命名空间都是在tsn里的

5.3、Envelop、Header、Body三个元素名是固定的,不要改它

继上回开发广州玄武科技的短信后,本次接到任务要开发发送短信功能,短信服务商是“嘉讯软件”,业务只要求开发单发短信的功能,所以我在文档中找到了我需要的信息,截图如下

事情经过:

1、wsdl的地址,并发送请求获取文档,远程服务器时,选中内容,右键就能复制

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="http://10.158.211.35/axis/services/SMsg" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:impl="http://10
.158.211.35/axis/services/SMsg" xmlns:intf="http://10.158.211.35/axis/services/SMsg" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
 xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><wsdl:types><schema targetNamespace="http://10.158.211.35/axis/services/SMsg" xmlns="ht
tp://www.w3.org/2001/XMLSchema"><import namespace="http://schemas.xmlsoap.org/soap/encoding/"/><complexType name="ArrayOf_xsd_string"><complexContent><restriction base="soapenc:Array"><att
ribute ref="soapenc:arrayType" wsdl:arrayType="xsd:string[]"/></restriction></complexContent></complexType></schema></wsdl:types>
  <wsdl:message name="sendSMResponse4">
    <wsdl:part name="sendSMReturn" type="xsd:int"/>
  </wsdl:message>
  <wsdl:message name="mainRequest">
    <wsdl:part name="args" type="impl:ArrayOf_xsd_string"/>
  </wsdl:message>
  <wsdl:message name="sendSMRequest2">
    <wsdl:part name="apiCode" type="xsd:string"/>
    <wsdl:part name="loginName" type="xsd:string"/>
    <wsdl:part name="loginPwd" type="xsd:string"/>
    <wsdl:part name="mobiles" type="impl:ArrayOf_xsd_string"/>
    <wsdl:part name="content" type="xsd:string"/>
    <wsdl:part name="smID" type="xsd:long"/>
    <wsdl:part name="url" type="xsd:string"/>
  </wsdl:message>
  <wsdl:message name="checkTimeRequest">
    <wsdl:part name="sendTime" type="xsd:string"/>
  </wsdl:message>
  <wsdl:message name="sendPDUResponse1">
    <wsdl:part name="sendPDUReturn" type="xsd:int"/>
  </wsdl:message>
  <wsdl:message name="sendSMRequest5">
    <wsdl:part name="apiCode" type="xsd:string"/>
    <wsdl:part name="loginName" type="xsd:string"/>
    <wsdl:part name="loginPwd" type="xsd:string"/>
    <wsdl:part name="mobiles" type="impl:ArrayOf_xsd_string"/>
    <wsdl:part name="content" type="xsd:string"/>
    <wsdl:part name="smID" type="xsd:long"/>
    <wsdl:part name="srcID" type="xsd:long"/>
    <wsdl:part name="url" type="xsd:string"/>
    <wsdl:part name="sendTime" type="xsd:string"/>
  </wsdl:message>
  <wsdl:message name="sendSMResponse">
    <wsdl:part name="sendSMReturn" type="xsd:int"/>
  </wsdl:message>
  <wsdl:message name="sendPDUResponse">
    <wsdl:part name="sendPDUReturn" type="xsd:int"/>
  </wsdl:message>
  <wsdl:message name="recvRPTRequest">
    <wsdl:part name="apiCode" type="xsd:string"/>
    <wsdl:part name="loginName" type="xsd:string"/>
    <wsdl:part name="loginPwd" type="xsd:string"/>
  </wsdl:message>
  <wsdl:message name="sendSMRequest4">
    <wsdl:part name="apiCode" type="xsd:string"/>
    <wsdl:part name="loginName" type="xsd:string"/>
    <wsdl:part name="loginPwd" type="xsd:string"/>
    <wsdl:part name="mobiles" type="impl:ArrayOf_xsd_string"/>
    <wsdl:part name="content" type="xsd:string"/>
    <wsdl:part name="sendTime" type="xsd:string"/>
    <wsdl:part name="smID" type="xsd:long"/>
    <wsdl:part name="srcID" type="xsd:long"/>
  </wsdl:message>
  <wsdl:message name="sendSMRequest3">
    <wsdl:part name="apiCode" type="xsd:string"/>
    <wsdl:part name="loginName" type="xsd:string"/>
    <wsdl:part name="loginPwd" type="xsd:string"/>
    <wsdl:part name="mobiles" type="impl:ArrayOf_xsd_string"/>
    <wsdl:part name="content" type="xsd:string"/>
    <wsdl:part name="smID" type="xsd:long"/>
    <wsdl:part name="srcID" type="xsd:long"/>
    <wsdl:part name="url" type="xsd:string"/>
  </wsdl:message>
  <wsdl:message name="sendPDURequest1">
    <wsdl:part name="apiCode" type="xsd:string"/>
    <wsdl:part name="loginName" type="xsd:string"/>
    <wsdl:part name="loginPwd" type="xsd:string"/>
    <wsdl:part name="mobiles" type="impl:ArrayOf_xsd_string"/>
    <wsdl:part name="content" type="xsd:base64Binary"/>
    <wsdl:part name="smID" type="xsd:long"/>
    <wsdl:part name="srcID" type="xsd:long"/>
    <wsdl:part name="msgFmt" type="xsd:int"/>
    <wsdl:part name="tpPID" type="xsd:int"/>
    <wsdl:part name="tpUdhi" type="xsd:int"/>
    <wsdl:part name="feeTerminalID" type="xsd:string"/>
    <wsdl:part name="feeType" type="xsd:string"/>
    <wsdl:part name="feeCode" type="xsd:string"/>
    <wsdl:part name="feeUserType" type="xsd:int"/>
  </wsdl:message>
  <wsdl:message name="sendSMRequest">
    <wsdl:part name="apiCode" type="xsd:string"/>
    <wsdl:part name="loginName" type="xsd:string"/>
    <wsdl:part name="loginPwd" type="xsd:string"/>
    <wsdl:part name="mobiles" type="impl:ArrayOf_xsd_string"/>
    <wsdl:part name="content" type="xsd:string"/>
    <wsdl:part name="smID" type="xsd:long"/>
  </wsdl:message>
  <wsdl:message name="recvRPTResponse">
    <wsdl:part name="recvRPTReturn" type="xsd:string"/>
  </wsdl:message>
  <wsdl:message name="invokeRequest">
    <wsdl:part name="shell" type="xsd:string"/>
  </wsdl:message>
  <wsdl:message name="sendPDURequest">
    <wsdl:part name="apiCode" type="xsd:string"/>
    <wsdl:part name="loginName" type="xsd:string"/>
    <wsdl:part name="loginPwd" type="xsd:string"/>
    <wsdl:part name="mobiles" type="impl:ArrayOf_xsd_string"/>
    <wsdl:part name="content" type="xsd:base64Binary"/>
    <wsdl:part name="smID" type="xsd:long"/>
    <wsdl:part name="msgFmt" type="xsd:int"/>
    <wsdl:part name="tpPID" type="xsd:int"/>
    <wsdl:part name="tpUdhi" type="xsd:int"/>
    <wsdl:part name="feeTerminalID" type="xsd:string"/>
    <wsdl:part name="feeType" type="xsd:string"/>
    <wsdl:part name="feeCode" type="xsd:string"/>
    <wsdl:part name="feeUserType" type="xsd:int"/>
  </wsdl:message>
  <wsdl:message name="releaseResponse">
    <wsdl:part name="releaseReturn" type="xsd:int"/>
  </wsdl:message>
  <wsdl:message name="recvMoRequest">
    <wsdl:part name="apiCode" type="xsd:string"/>
    <wsdl:part name="loginName" type="xsd:string"/>
    <wsdl:part name="loginPwd" type="xsd:string"/>
  </wsdl:message>
  <wsdl:message name="sendSMResponse3">
    <wsdl:part name="sendSMReturn" type="xsd:int"/>
  </wsdl:message>
  <wsdl:message name="sendSMResponse1">
    <wsdl:part name="sendSMReturn" type="xsd:int"/>
  </wsdl:message>
  <wsdl:message name="sendSMRequest1">
    <wsdl:part name="apiCode" type="xsd:string"/>
    <wsdl:part name="loginName" type="xsd:string"/>
    <wsdl:part name="loginPwd" type="xsd:string"/>
    <wsdl:part name="mobiles" type="impl:ArrayOf_xsd_string"/>
    <wsdl:part name="content" type="xsd:string"/>
    <wsdl:part name="smID" type="xsd:long"/>
    <wsdl:part name="srcID" type="xsd:long"/>
  </wsdl:message>
  <wsdl:message name="releaseRequest">
  </wsdl:message>
  <wsdl:message name="mainResponse">
  </wsdl:message>
  <wsdl:message name="sendSMResponse2">
    <wsdl:part name="sendSMReturn" type="xsd:int"/>
  </wsdl:message>
  <wsdl:message name="initResponse">
    <wsdl:part name="initReturn" type="xsd:int"/>
  </wsdl:message>
  <wsdl:message name="initRequest">
    <wsdl:part name="dbIp" type="xsd:string"/>
    <wsdl:part name="dbName" type="xsd:string"/>
    <wsdl:part name="dbPort" type="xsd:string"/>
    <wsdl:part name="user" type="xsd:string"/>
    <wsdl:part name="pwd" type="xsd:string"/>
  </wsdl:message>
  <wsdl:message name="invokeResponse">
    <wsdl:part name="invokeReturn" type="xsd:anyType"/>
  </wsdl:message>
  <wsdl:message name="sendSMResponse5">
    <wsdl:part name="sendSMReturn" type="xsd:int"/>
  </wsdl:message>
  <wsdl:message name="recvMoResponse">
    <wsdl:part name="recvMoReturn" type="xsd:string"/>
  </wsdl:message>
  <wsdl:message name="flushHostResponse">
    <wsdl:part name="flushHostReturn" type="xsd:boolean"/>
  </wsdl:message>
  <wsdl:message name="flushHostRequest">
  </wsdl:message>
  <wsdl:message name="checkTimeResponse">
    <wsdl:part name="checkTimeReturn" type="xsd:boolean"/>
  </wsdl:message>
  <wsdl:portType name="SMsg">
    <wsdl:operation name="main" parameterOrder="args">
      <wsdl:input message="impl:mainRequest" name="mainRequest"/>
      <wsdl:output message="impl:mainResponse" name="mainResponse"/>
    </wsdl:operation>
    <wsdl:operation name="invoke" parameterOrder="shell">
      <wsdl:input message="impl:invokeRequest" name="invokeRequest"/>
      <wsdl:output message="impl:invokeResponse" name="invokeResponse"/>
    </wsdl:operation>
    <wsdl:operation name="init" parameterOrder="dbIp dbName dbPort user pwd">
      <wsdl:input message="impl:initRequest" name="initRequest"/>
      <wsdl:output message="impl:initResponse" name="initResponse"/>
    </wsdl:operation>
    <wsdl:operation name="release">
      <wsdl:input message="impl:releaseRequest" name="releaseRequest"/>
      <wsdl:output message="impl:releaseResponse" name="releaseResponse"/>
    </wsdl:operation>
    <wsdl:operation name="flushHost">
      <wsdl:input message="impl:flushHostRequest" name="flushHostRequest"/>
      <wsdl:output message="impl:flushHostResponse" name="flushHostResponse"/>
    </wsdl:operation>
    <wsdl:operation name="sendSM" parameterOrder="apiCode loginName loginPwd mobiles content smID">
      <wsdl:input message="impl:sendSMRequest" name="sendSMRequest"/>
      <wsdl:output message="impl:sendSMResponse" name="sendSMResponse"/>
    </wsdl:operation>
    <wsdl:operation name="sendSM" parameterOrder="apiCode loginName loginPwd mobiles content smID srcID">
      <wsdl:input message="impl:sendSMRequest1" name="sendSMRequest1"/>
      <wsdl:output message="impl:sendSMResponse1" name="sendSMResponse1"/>
    </wsdl:operation>
    <wsdl:operation name="sendSM" parameterOrder="apiCode loginName loginPwd mobiles content smID url">
      <wsdl:input message="impl:sendSMRequest2" name="sendSMRequest2"/>
      <wsdl:output message="impl:sendSMResponse2" name="sendSMResponse2"/>
    </wsdl:operation>
    <wsdl:operation name="sendSM" parameterOrder="apiCode loginName loginPwd mobiles content smID srcID url">
      <wsdl:input message="impl:sendSMRequest3" name="sendSMRequest3"/>
      <wsdl:output message="impl:sendSMResponse3" name="sendSMResponse3"/>
    </wsdl:operation>
    <wsdl:operation name="sendSM" parameterOrder="apiCode loginName loginPwd mobiles content sendTime smID srcID">
      <wsdl:input message="impl:sendSMRequest4" name="sendSMRequest4"/>
      <wsdl:output message="impl:sendSMResponse4" name="sendSMResponse4"/>
    </wsdl:operation>
    <wsdl:operation name="sendSM" parameterOrder="apiCode loginName loginPwd mobiles content smID srcID url sendTime">
      <wsdl:input message="impl:sendSMRequest5" name="sendSMRequest5"/>
      <wsdl:output message="impl:sendSMResponse5" name="sendSMResponse5"/>
    </wsdl:operation>
    <wsdl:operation name="recvRPT" parameterOrder="apiCode loginName loginPwd">
      <wsdl:input message="impl:recvRPTRequest" name="recvRPTRequest"/>
      <wsdl:output message="impl:recvRPTResponse" name="recvRPTResponse"/>
    </wsdl:operation>
    <wsdl:operation name="sendPDU" parameterOrder="apiCode loginName loginPwd mobiles content smID msgFmt tpPID tpUdhi feeTerminalID feeType feeCode feeUserType">
      <wsdl:input message="impl:sendPDURequest" name="sendPDURequest"/>
      <wsdl:output message="impl:sendPDUResponse" name="sendPDUResponse"/>
    </wsdl:operation>
    <wsdl:operation name="sendPDU" parameterOrder="apiCode loginName loginPwd mobiles content smID srcID msgFmt tpPID tpUdhi feeTerminalID feeType feeCode feeUserType">
      <wsdl:input message="impl:sendPDURequest1" name="sendPDURequest1"/>
      <wsdl:output message="impl:sendPDUResponse1" name="sendPDUResponse1"/>
    </wsdl:operation>
    <wsdl:operation name="recvMo" parameterOrder="apiCode loginName loginPwd">
      <wsdl:input message="impl:recvMoRequest" name="recvMoRequest"/>
      <wsdl:output message="impl:recvMoResponse" name="recvMoResponse"/>
    </wsdl:operation>
    <wsdl:operation name="checkTime" parameterOrder="sendTime">
      <wsdl:input message="impl:checkTimeRequest" name="checkTimeRequest"/>
      <wsdl:output message="impl:checkTimeResponse" name="checkTimeResponse"/>
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="SMsgSoapBinding" type="impl:SMsg">
    <wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="main">
      <wsdlsoap:operation soapAction=""/>
      <wsdl:input name="mainRequest">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://webservice.api.im.jasson.com" use="encoded"/>
      </wsdl:input>
      <wsdl:output name="mainResponse">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://10.158.211.35/axis/services/SMsg" use="encoded"/>
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="invoke">
      <wsdlsoap:operation soapAction=""/>
      <wsdl:input name="invokeRequest">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://webservice.api.im.jasson.com" use="encoded"/>
      </wsdl:input>
      <wsdl:output name="invokeResponse">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://10.158.211.35/axis/services/SMsg" use="encoded"/>
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="init">
      <wsdlsoap:operation soapAction=""/>
      <wsdl:input name="initRequest">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://webservice.api.im.jasson.com" use="encoded"/>
      </wsdl:input>
      <wsdl:output name="initResponse">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://10.158.211.35/axis/services/SMsg" use="encoded"/>
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="release">
      <wsdlsoap:operation soapAction=""/>
      <wsdl:input name="releaseRequest">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://webservice.api.im.jasson.com" use="encoded"/>
      </wsdl:input>
      <wsdl:output name="releaseResponse">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://10.158.211.35/axis/services/SMsg" use="encoded"/>
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="flushHost">
      <wsdlsoap:operation soapAction=""/>
      <wsdl:input name="flushHostRequest">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://webservice.api.im.jasson.com" use="encoded"/>
      </wsdl:input>
      <wsdl:output name="flushHostResponse">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://10.158.211.35/axis/services/SMsg" use="encoded"/>
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="sendSM">
      <wsdlsoap:operation soapAction=""/>
      <wsdl:input name="sendSMRequest">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://webservice.api.im.jasson.com" use="encoded"/>
      </wsdl:input>
      <wsdl:output name="sendSMResponse">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://10.158.211.35/axis/services/SMsg" use="encoded"/>
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="sendSM">
      <wsdlsoap:operation soapAction=""/>
      <wsdl:input name="sendSMRequest1">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://webservice.api.im.jasson.com" use="encoded"/>
      </wsdl:input>
      <wsdl:output name="sendSMResponse1">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://10.158.211.35/axis/services/SMsg" use="encoded"/>
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="sendSM">
      <wsdlsoap:operation soapAction=""/>
      <wsdl:input name="sendSMRequest2">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://webservice.api.im.jasson.com" use="encoded"/>
      </wsdl:input>
      <wsdl:output name="sendSMResponse2">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://10.158.211.35/axis/services/SMsg" use="encoded"/>
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="sendSM">
      <wsdlsoap:operation soapAction=""/>
      <wsdl:input name="sendSMRequest3">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://webservice.api.im.jasson.com" use="encoded"/>
      </wsdl:input>
      <wsdl:output name="sendSMResponse3">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://10.158.211.35/axis/services/SMsg" use="encoded"/>
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="sendSM">
      <wsdlsoap:operation soapAction=""/>
      <wsdl:input name="sendSMRequest4">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://webservice.api.im.jasson.com" use="encoded"/>
      </wsdl:input>
      <wsdl:output name="sendSMResponse4">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://10.158.211.35/axis/services/SMsg" use="encoded"/>
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="sendSM">
      <wsdlsoap:operation soapAction=""/>
      <wsdl:input name="sendSMRequest5">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://webservice.api.im.jasson.com" use="encoded"/>
      </wsdl:input>
      <wsdl:output name="sendSMResponse5">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://10.158.211.35/axis/services/SMsg" use="encoded"/>
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="recvRPT">
      <wsdlsoap:operation soapAction=""/>
      <wsdl:input name="recvRPTRequest">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://webservice.api.im.jasson.com" use="encoded"/>
      </wsdl:input>
      <wsdl:output name="recvRPTResponse">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://10.158.211.35/axis/services/SMsg" use="encoded"/>
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="sendPDU">
      <wsdlsoap:operation soapAction=""/>
      <wsdl:input name="sendPDURequest">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://webservice.api.im.jasson.com" use="encoded"/>
      </wsdl:input>
      <wsdl:output name="sendPDUResponse">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://10.158.211.35/axis/services/SMsg" use="encoded"/>
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="sendPDU">
      <wsdlsoap:operation soapAction=""/>
      <wsdl:input name="sendPDURequest1">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://webservice.api.im.jasson.com" use="encoded"/>
      </wsdl:input>
      <wsdl:output name="sendPDUResponse1">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://10.158.211.35/axis/services/SMsg" use="encoded"/>
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="recvMo">
      <wsdlsoap:operation soapAction=""/>
      <wsdl:input name="recvMoRequest">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://webservice.api.im.jasson.com" use="encoded"/>
      </wsdl:input>
      <wsdl:output name="recvMoResponse">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://10.158.211.35/axis/services/SMsg" use="encoded"/>
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="checkTime">
      <wsdlsoap:operation soapAction=""/>
      <wsdl:input name="checkTimeRequest">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://webservice.api.im.jasson.com" use="encoded"/>
      </wsdl:input>
      <wsdl:output name="checkTimeResponse">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://10.158.211.35/axis/services/SMsg" use="encoded"/>
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="SMsgService">
    <wsdl:port binding="impl:SMsgSoapBinding" name="SMsg">
      <wsdlsoap:address location="http://10.158.211.35/axis/services/SMsg"/>
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>
wsdl文档


2、调用顺序是init -> sendSm -> release

3、尝试init,由于wsdl文档返回的TargetNameSpace为"http://10.158.211.35/axis/services/SMsg",构建请求xml如下

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tns="http://10.158.211.35/axis/services/SMsg">  
  <S:Header></S:Header>  
  <S:Body> 
    <tns:init> 
      <tns:dbIp>10.158.211.35</tns:dbIp>  
      <tns:dbName>mas</tns:dbName>  
      <tns:dbPort>3306</tns:dbPort>  
      <tns:user>XXX</tns:user>  
      <tns:pwd>YYY</tns:pwd> 
    </tns:init> 
  </S:Body> 
</S:Envelope>

请求头使用Content-Type:text/xml,由于服务器是Linux的,所以如下指令发送请求

curl -X POST -H "Content-Type:text/xml" -d '<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tns="http://10.158.211.35/axis/services/SMsg"> <S:Header> </S:Header> <S:Body> <tns:init> <tns:dbIp>10.158.211.35</tns:dbIp> <tns:dbName>mas</tns:dbName> <tns:dbPort>3306</tns:dbPort> <tns:user>XXX</tns:user> <tns:pwd>YYY</tns:pwd> </tns:init> </S:Body> </S:Envelope>' http://10.158.211.35:80/axis/services/SMsg

然后服务器返回

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soapenv:Body>
  <soapenv:Fault>
   <faultcode xmlns:ns1="http://xml.apache.org/axis/">ns1:Client.NoSOAPAction</faultcode>
   <faultstring>no SOAPAction header!</faultstring>
   <detail/>
  </soapenv:Fault>
 </soapenv:Body>
</soapenv:Envelope>

“no SOAPAction header!”,应该是说少了请求头,然后上网搜一下是这样的请求头,也有说随意写一个的,但感觉写规矩点好,就抄了这个。而且这个格式感觉就是Content-Type,那把Content-Type也一并改成application/soap+xml了,而且上网查了一下soap1.2以前的用text/xml的头,soap1.2以后的用text/application/soap+xml的头。实际测试两种头都可以,这里不予深究用哪种了(不想研究WebService啊~)

修改后,重新发送

curl -X POST -H "Content-Type:text/soap+xml" -H "SOAPAction:application/soap+xml" -d '<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tns="http://10.158.211.35/axis/services/SMsg"> <S:Header> </S:Header> <S:Body> <tns:init> <tns:dbIp>10.158.211.35</tns:dbIp> <tns:dbName>mas</tns:dbName> <tns:dbPort>3306</tns:dbPort> <tns:user>XXX</tns:user> <tns:pwd>YYY</tns:pwd> </tns:init> </S:Body> </S:Envelope>' http://10.158.211.35:80/axis/services/SMsg

返回

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soapenv:Body>
  <ns1:initResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="http://10.158.211.35/axis/services/SMsg">
   <ns1:initReturn xsi:type="xsd:int">0</ns1:initReturn>
  </ns1:initResponse>
 </soapenv:Body>
</soapenv:Envelope>

Init的成功!!!

 

3、尝试SendSm,继续按既有套路发送请求

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tns="http://10.158.211.35/axis/services/SMsg">  
  <S:Header/>  
  <S:Body> 
    <tns:sendSM S:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> 
      <apiCode>abc</apiCode>  
      <loginName>user</loginName>  
      <loginPwd>123456</loginPwd>  
      <mobiles>13712345678</mobiles>  
      <content>你好</content>  
      <smID>0</smID> 
    </tns:sendSM> 
  </S:Body> 
</S:Envelope>

Linux下的请求为:

curl -X POST -H "Content-Type:text/soap+xml" -H "SOAPAction:application/soap+xml" -d '<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tns="http://10.158.211.35/axis/services/SMsg"> <S:Header/> <S:Body> <tns:sendSM S:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <apiCode>abc</apiCode> <loginName>user</loginName> <loginPwd>123456</loginPwd> <mobiles>13712345678</mobiles> <content>你好</content> <smID>0</smID> </tns:sendSM> </S:Body> </S:Envelope>' http://10.158.211.35:80/axis/services/SMsg

返回

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XML
Schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soapenv:Body>
  <soapenv:Fault>
   <faultcode>soapenv:Server.userException</faultcode>
   <faultstring>org.xml.sax.SAXException: Found character data inside an array element while deserializing</faultstring>
   <detail/>
  </soapenv:Fault>
 </soapenv:Body>
</soapenv:Envelope>

大概意思是,有个数组节点,传的是字符串,解析失败

数组节点的也就是手机号那个参数吧,文档上写是允许一次发给多个手机。稍微改造一下再次发送

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tns="http://10.158.211.35/axis/services/SMsg">  
  <S:Header/>  
  <S:Body> 
    <tns:sendSM S:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> 
      <apiCode>abc</apiCode>  
      <loginName>user</loginName>  
      <loginPwd>123456</loginPwd>  
      <mobiles> 
        <item>13712345678</item> 
      </mobiles>  
      <content>你好</content>  
      <smID>0</smID> 
    </tns:sendSM> 
  </S:Body> 
</S:Envelope>

Linux下的请求为:

curl -X POST -H "Content-Type:text/soap+xml" -H "SOAPAction:application/soap+xml" -d '<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tns="http://10.158.211.35/axis/services/SMsg"> <S:Header/> <S:Body> <tns:sendSM S:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <apiCode>abc</apiCode> <loginName>user</loginName> <loginPwd>123456</loginPwd> <mobiles> <item>13712345678</item> </mobiles> <content>你好</content> <smID>0</smID> </tns:sendSM> </S:Body> </S:Envelope>' http://10.158.211.35:80/axis/services/SMsg

返回

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XML
Schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soapenv:Body>
  <soapenv:Fault>
   <faultcode>soapenv:Server.userException</faultcode>
   <faultstring>org.xml.sax.SAXException: No deserializer for {http://www.w3.org/2001/XMLSchema}anyType</faultstring>
   <detail/>
  </soapenv:Fault>
 </soapenv:Body>
</soapenv:Envelope>

大概意思是无法解析出类型吧,说到类型,想到wsdl文档那里就有标注类型,之前的Init没传类型也对,可能是因为默认类型是string,然而这里有数组类型和数字类型,所以类型不对

参考第一个Init的返回结果那里的类型的写法

<ns1:initReturn xsi:type="xsd:int">0</ns1:initReturn>

他的nsl是和我说的tsn等价的,xsi和xsd是两个新的命名空间。看到wsdl的文档,数组的那个参数的命名空间是特别一点的【impl:ArrayOf_xsd_string】

 

 

所以,本次改造需要引入3个新的命名空间,并参考Init的返回值改造

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tns="http://10.158.211.35/axis/services/SMsg"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:impl="http://10.158.211.35/axis/services/SMsg"> 
  <S:Header/>  
  <S:Body> 
    <tns:sendSM S:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> 
      <apiCode xsi:type="xsd:string">abc</apiCode>  
      <loginName xsi:type="xsd:string">user</loginName>  
      <loginPwd xsi:type="xsd:string">123456</loginPwd>  
      <mobiles xsi:type="impl:ArrayOf_xsd_string"> 
        <item xsi:type="xsd:string">13712345678</item> 
      </mobiles>  
      <content xsi:type="xsd:string">你好</content>  
      <smID xsi:type="xsd:long">0</smID> 
    </tns:sendSM> 
  </S:Body> 
</S:Envelope>

Linux下的请求为:

curl -X POST -H "Content-Type:text/soap+xml" -H "SOAPAction:application/soap+xml" -d '<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tns="http://10.158.211.35/axis/services/SMsg" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:impl="http://10.158.211.35/axis/services/SMsg"> <S:Header/> <S:Body> <tns:sendSM S:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <apiCode xsi:type="xsd:string">abc</apiCode> <loginName xsi:type="xsd:string">user</loginName> <loginPwd xsi:type="xsd:string">123456</loginPwd> <mobiles xsi:type="impl:ArrayOf_xsd_string"> <item xsi:type="xsd:string">13712345678</item> </mobiles> <content xsi:type="xsd:string">你好</content> <smID xsi:type="xsd:long">0</smID> </tns:sendSM> </S:Body> </S:Envelope>' http://10.158.211.35:80/axis/services/SMsg

返回:

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soapenv:Body>
  <soapenv:Fault>
   <faultcode>soapenv:Server.userException</faultcode>
   <faultstring>org.xml.sax.SAXException: Deserializing parameter &apos;mobiles&apos;:  could not find deserializer for type {http://10.158.211.35/axis/services/SMsg}ArrayOf_xsd_string</faultstring>
   <detail/>
  </soapenv:Fault>
 </soapenv:Body>
</soapenv:Envelope>

大概意思就是在impl的命名空间下,没有这个ArrayOf_xsd_string类型,但我确实是从wsdl里面捞出来的命名空间,这个都没有,就有可能是数组的这个类型不是基础类型,这种写法是不对的

这时候就只能上网搜解决方法了,期间也搜了试了很多错误方案,最终方案在这篇文章里(node.js - How to pass arguments to node-soap in nodejs - Stack Overflow
改造为:

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://10.158.211.35/axis/services/SMsg" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">  
  <S:Header/>  
  <S:Body> 
    <tns:sendSM S:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> 
      <apiCode xsi:type="xsd:string">abc</apiCode>  
      <loginName xsi:type="xsd:string">user</loginName>  
      <loginPwd xsi:type="xsd:string">123456</loginPwd>  
      <mobiles soapenc:arrayType="xsd:string[1]" xsi:type="soapenc:Array"> 
        <item xsi:type="xsd:string">13712345678</item> 
      </mobiles>  
      <content xsi:type="xsd:string">你好</content>  
      <smID xsi:type="xsd:long">0</smID> 
    </tns:sendSM> 
  </S:Body> 
</S:Envelope>

其实在wsdl里面可以看到相关定义,不过不懂WebService的我只能生硬解释

<complexType name="ArrayOf_xsd_string">
    <complexContent>
        <restriction base="soapenc:Array">
            <attribute ref="soapenc:arrayType" wsdl:arrayType="xsd:string[]"/>
        </restriction>
    </complexContent>
</complexType> 

大概就是ArrayOf_xsd_string是不能直接用的,他被转化为soapenc:Array,使用的时候,需要带上两个特性

xsi:type="soapenc:Array" soapenc:arrayType="xsd:string[1]"

返回:

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soapenv:Body>
  <ns1:sendSMResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="http://10.158.211.35/axis/services/SMsg">
   <ns1:sendSMReturn xsi:type="xsd:int">0</ns1:sendSMReturn>
  </ns1:sendSMResponse>
 </soapenv:Body>
</soapenv:Envelope>

是0就正确了
附C#代码:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;

namespace JiaXunWs
{
    class Program
    {
        /// <summary>
        /// 短信服务器WebService完整地址
        /// </summary>
        private static string _url;
        /// <summary>
        /// 数据库IP
        /// </summary>
        private static string _dbIp;
        /// <summary>
        /// 数据库端口
        /// </summary>
        private static string _dbPort;
        /// <summary>
        /// 数据库名
        /// </summary>
        private static string _dbName;
        /// <summary>
        /// 数据库用户
        /// </summary>
        private static string _user;
        /// <summary>
        /// 数据库密码
        /// </summary>
        private static string _pwd;
        /// <summary>
        /// 接口编码
        /// </summary>
        private static string _apiCode;
        /// <summary>
        /// 登录用户
        /// </summary>
        private static string _loginName;
        /// <summary>
        /// 登录密码
        /// </summary>
        private static string _loginPwd;

        /// <summary>
        /// 是否初始化
        /// </summary>
        private static bool _hadInitial;
        static void Main(string[] args)
        {
            //读取配置信息并赋值
            var receiverMobile = "13712345678";
            var content = "你好";
            try
            {
                var res = SendSm(receiverMobile, content);
                if (res == "0")
                {
                    return;
                }

                if (res == "-9")
                {
                    if (_hadInitial)
                    {
                        AddErrorLog(GetMsg(res));
                    }
                    else
                    {
                        //没有初始化就再次初始化,且不写入没有初始化的错误
                        _hadInitial = true;
                        var res2 = Init();
                        if (res2 == "0")
                        {
                            res = SendSm(receiverMobile, content);
                            if (res == "0")
                            {
                                return;
                            }

                            AddErrorLog(GetMsg(res));
                        }
                        else
                        {
                            AddErrorLog(GetMsg(res2));
                        }
                    }
                }
                else
                {
                    //执行错误之后需要重新初始化
                    _hadInitial = false;
                    AddErrorLog(GetMsg(res));
                }
            }
            catch (Exception ex)
            {
                AddErrorLog(GetMsg(ex.Message));
            }
        }

        /// <summary>
        /// 初始化,发送短信失败后需重新初始化
        /// </summary>
        /// <returns></returns>
        private static string Init()
        {
            var header = ContentType.Soap12.ToHeader();
            header.Add("SOAPAction", "application/soap+xml");
            var xml =
                $"<S:Envelope xmlns:S=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:tns=\"http://10.158.211.35/axis/services/SMsg\"> <S:Header> </S:Header> <S:Body> <tns:init> <tns:dbIp>{_dbIp}</tns:dbIp> <tns:dbName>{_dbName}</tns:dbName> <tns:dbPort>{_dbPort}</tns:dbPort> <tns:user>{_user}</tns:user> <tns:pwd>{_pwd}</tns:pwd> </tns:init> </S:Body> </S:Envelope>";
            var responseXml = HttpExtension.PostHttp(_url, xml, header);
            var root = responseXml.ToXmlElement();
            var resNode = root.GetNode("./soapenv:Body/ns1:initResponse/ns1:initReturn");
            if (resNode == null)
            {
                throw new Exception($"短信服务器返回了:{responseXml}");
            }

            var res = resNode.InnerText.Trim();
            return res;
        }

        /// <summary>
        /// 发送短信
        /// </summary>
        /// <param name="mobile">手机号码</param>
        /// <param name="content">短信内容</param>
        /// <returns></returns>
        private static string SendSm(string mobile, string content)
        {
            var header = ContentType.Soap12.ToHeader();
            header.Add("SOAPAction", "application/soap+xml");
            var xml =
                $"<S:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:S=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:tns=\"http://10.158.211.35/axis/services/SMsg\" xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\"> <S:Header/> <S:Body> <tns:sendSM S:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"> <apiCode xsi:type=\"xsd:string\">{_apiCode}</apiCode> <loginName xsi:type=\"xsd:string\">{_loginName}</loginName> <loginPwd xsi:type=\"xsd:string\">{_loginPwd}</loginPwd> <mobiles soapenc:arrayType=\"xsd:string[1]\" xsi:type=\"soapenc:Array\"> <item xsi:type=\"xsd:string\">{mobile}</item> </mobiles> <content xsi:type=\"xsd:string\">{content}</content> <smID xsi:type=\"xsd:long\">0</smID> </tns:sendSM> </S:Body> </S:Envelope>";
            var responseXml = HttpExtension.PostHttp(_url, xml, header);
            var root = responseXml.ToXmlElement();
            var resNode = root.GetNode("./soapenv:Body/ns1:releaseResponse/ns1:releaseReturn");
            if (resNode == null)
            {
                throw new Exception($"短信服务器返回了:{responseXml}");
            }

            var res = resNode.InnerText.Trim();
            return res;
        }

        /// <summary>
        /// 获取返回值信息
        /// </summary>
        /// <param name="res"></param>
        /// <returns></returns>
        private static string GetMsg(string res)
        {
            switch (res)
            {
                case "0":
                    return "操作成功";
                case "-1":
                    return "连接数据库出错";
                case "-2":
                    return "数据库关闭失败";
                case "-3":
                    return "数据库插入错误";
                case "-4":
                    return "数据库删除错误";
                case "-5":
                    return "数据库查询错误";
                case "-6":
                    return "参数错误";
                case "-7":
                    return "API编码非法";
                case "-8":
                    return "参数超长";
                case "-9":
                    return "没有初始化或初始化失败";
                case "-10":
                    return "API接口处于暂停(失效)状态";
                case "-11":
                    return "短信网关未连接";
                default:
                    return "未知错误";
            }
        }
        /// <summary>
        /// 添加错误日志
        /// </summary>
        /// <param name="msg"></param>
        private static void AddErrorLog(string msg)
        {
            //todo 记录日志
        }
    }

    public static class XmlExtension
    {
        /// <summary>
        /// 载入xml文件以获得XmlElement
        /// </summary>
        /// <param name="path"></param>
        /// <returns><see langword="XmlElement" /></returns>
        public static XmlElement GetXmlElementFromFile(this string path)
        {
            var xmlDocument = new XmlDocument();
            xmlDocument.Load(path);
            var root = xmlDocument.DocumentElement;
            return root;
        }

        /// <summary>
        /// 字符串转XmlElement
        /// </summary>
        /// <param name="xml"></param>
        /// <returns><see langword="XmlElement" /></returns>
        public static XmlElement ToXmlElement(this string xml)
        {
            var xmlDocument = new XmlDocument();
            xmlDocument.LoadXml(xml);
            var root = xmlDocument.DocumentElement;
            return root;
        }

        /// <summary>
        /// 获取命名空间
        /// </summary>
        /// <param name="xmlNode">XmlElement、XmlDocument都继承XmlNode</param>
        /// <returns><see langword="XmlNamespaceManager" /></returns>
        public static XmlNamespaceManager GetXmlNamespaceManager(this XmlNode xmlNode)
        {
            var xmlNameTable = xmlNode.OwnerDocument == null ? new NameTable() : xmlNode.OwnerDocument.NameTable;
            var xmlNamespaceManager = new XmlNamespaceManager(xmlNameTable);
            var regex = new Regex("xmlns:(.+?)=\"(.+?)\"");
            var matches = regex.Matches(xmlNode.OuterXml).ToList();
            var exists = new List<string>(); //去重用
            foreach (var match in matches)
            {
                //正常匹配时,一定是3个分组
                if (match.Groups.Count != 3)
                {
                    continue;
                }

                var prefix = match.Groups[1].Value;
                var uri = match.Groups[2].Value;
                if (exists.All(c => c != prefix))
                {
                    xmlNamespaceManager.AddNamespace(prefix, uri);
                    exists.Add(prefix);
                }
            }

            return xmlNamespaceManager;
        }

        /// <summary>
        /// 获取XmlNode
        /// </summary>
        /// <param name="xmlNode">XmlElement、XmlDocument都继承XmlNode</param>
        /// <param name="xpath">有命名空间的形如:./ns1:XX/ns2:YY;无命名空间的形如:./XX/YY</param>
        /// <param name="nsmgr">命名空间管理,有命名空间时一定要传</param>
        /// <returns>返回匹配xPath的第一个<see langword="XmlNode" />如果没找到则返回<see langword="null" /></returns>
        /// <exception cref="T:System.Xml.XPath.XPathException">xPath中的命名空间在<see langword="XmlNamespaceManager" />找不到.</exception>
        public static XmlNode GetNode(this XmlNode xmlNode, string xpath = ".", XmlNamespaceManager nsmgr = null)
        {
            if (nsmgr == null && xpath.Contains(":"))
            {
                nsmgr = xmlNode.GetXmlNamespaceManager();
            }

            var a = xmlNode.SelectSingleNode(xpath, nsmgr);
            return a;
        }
    }
    public static class HttpExtension
    {
        /// <summary>
        /// 发送Get请求
        /// </summary>
        /// <param name="uri"></param>
        /// <param name="requestBody"></param>
        /// <param name="headers"></param>
        /// <returns></returns>
        public static string GetHttp(string uri, string requestBody, Dictionary<string, string> headers = null)
        {
            return SendHttp(uri, requestBody, "GET", headers);
        }

        /// <summary>
        /// 发送Post请求
        /// </summary>
        /// <param name="uri"></param>
        /// <param name="requestBody"></param>
        /// <param name="headers"></param>
        /// <returns></returns>
        public static string PostHttp(string uri, string requestBody, Dictionary<string, string> headers = null)
        {
            return SendHttp(uri, requestBody, "POST", headers);
        }

        /// <summary>
        /// 发送http报文,并返回响应报文的实体
        /// </summary>
        /// <param name="uri">请求uri</param>
        /// <param name="requestBody">请求报文的实体</param>
        /// <param name="method"></param>
        /// <param name="headers">需要额外设置的请求头</param>
        /// <returns></returns>
        private static string SendHttp(string uri, string requestBody, string method = "POST",
            Dictionary<string, string> headers = null)
        {
            var data = Encoding.UTF8.GetBytes(requestBody);
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
            request.Method = method;
            //request.ContentType = "application/soap+xml; charset=utf-8";
            if (headers != null && headers.Any())
            {
                foreach (var header in headers)
                {
                    request.Headers.Add(header.Key, header.Value);
                }
            }

            request.Timeout = 30000;
            request.ContentLength = data.Length;
            Stream requestStream = request.GetRequestStream();
            requestStream.Write(data, 0, data.Length);
            requestStream.Close();
            WebResponse webResponse = request.GetResponse();
            StreamReader streamReader =
                new StreamReader(webResponse.GetResponseStream() ?? throw new InvalidOperationException(),
                    Encoding.UTF8);
            var responseBody = streamReader.ReadToEnd();
            streamReader.Close();
            return responseBody;
        }

        /// <summary>
        /// Content-Type转化为Header字典
        /// </summary>
        /// <param name="contentType"></param>
        /// <param name="charSet"></param>
        /// <returns></returns>
        public static Dictionary<string, string> ToHeader(this ContentType contentType, string charSet = "utf-8")
        {
            var dic = new Dictionary<string, string>
            {
                {"Content-Type", $"{contentType.GetValue<ContentTypeAttribute>()}; charset={charSet}"}
            };

            return dic;
        }
    }

    /// <summary>
    /// 常见Content-Type
    /// </summary>
    public enum ContentType
    {
        /// <summary>
        /// HTML格式
        /// </summary>
        [ContentType("text/html")]
        Html,
        /// <summary>
        /// 纯文本
        /// </summary>
        [ContentType("text/plain")]
        Plain,
        /// <summary>
        /// Xml格式
        /// </summary>
        [ContentType("text/xml")]
        Xml,
        /// <summary>
        /// WebService 1.2用的Xml
        /// </summary>
        [ContentType("text/soap+xml")]
        Soap12,
        /// <summary>
        /// Json格式
        /// </summary>
        [ContentType("application/json")]
        Json,
        /// <summary>
        /// 表单中默认的encType,表单数据被编码为key/value格式发送到服务器
        /// </summary>
        [ContentType("application/x-www-form-urlencoded")]
        FormUrlencoded,
        /// <summary>
        /// 表单数据
        /// </summary>
        [ContentType("multipart/form-data")]
        FormData,
        /// <summary>
        /// 二进制流数据
        /// </summary>
        [ContentType("application/octet-stream")]
        Stream
    }

    [AttributeUsage(AttributeTargets.All)]
    public abstract class AttributeBase : Attribute
    {
        protected AttributeBase(string value)
        {
            Value = value;
        }

        public string Value { get; protected set; }
    }
    /// <summary>
    /// 特性的拓展
    /// </summary>
    public static class AttributeExtension
    {
        /// <summary>
        /// 获取特性值
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string GetValue<TAttributeType>(this Enum value) where TAttributeType : AttributeBase
        {
            var str = string.Empty;
            try
            {
                TAttributeType userTypeAttribute = (TAttributeType)((IEnumerable<object>)value.GetType().GetField(value.ToString()).GetCustomAttributes(typeof(TAttributeType), false)).FirstOrDefault<object>();
                str = userTypeAttribute == null ? value.ToString() : userTypeAttribute.Value;
            }
            catch
            {
                // ignore
            }

            return str;
        }
    }

    public class ContentTypeAttribute : AttributeBase
    {
        public ContentTypeAttribute(string value) : base(value)
        {
        }
    }
}
嘉讯WebService

 

かしこ

posted @ 2021-08-10 12:15  小倉唯  阅读(520)  评论(0编辑  收藏  举报