前提
所遇問題爲調用webservice接口地址是https類型引發,程序C++。沒有用gsoap生成代碼來開發客戶端,因爲考慮到維護不方便,採用http封裝發送
【問題一】*(難度係數)
描述:調用地址爲https,直接發送會報驗證證書失敗。
說明:查閱資料總結很多情況作爲客戶端是不需要加載證書去驗證的,如果是雙向驗證的才需要生成客戶端證書進行驗證,這裏沒有用到。我這邊是單向的,所以直接設置爲不驗證證書和主機就行
解決:調整代碼,調整curl發送報文時不驗證證書:
curl_easy_setopt(curl,CURLOPT_NOSIGNAL,1);
curl_easy_setopt(curl,CURLOPT_USE_SSL,1);
curl_easy_setopt(curl,CURLOPT_SSL_VERIFYPEER,0); //設定爲不驗證證書
curl_easy_setopt(curl,CURLOPT_SSL_VERIFYHOST,0);
`
【問題二】**
描述:發送報文後,返回報錯:500,服務器內部錯誤,具體是報:no SOAPAction header。如下圖:
解決方法:在發送報文頭加上SOAPAction屬性
_headers = curl_slist_append(_headers,“SOAPAction: “””);
注意:報文頭添加屬性是不需要進行換行,直接追加就行。
即在代碼中要這樣寫:
std::string strConnect = "Connection: close";
std::string strUserAgent = "User-Agent: gSOAP/2.7";
std::string strConnectionType = "Content-Type: text/html; charset=UTF-8;";
std::string strSoapAction = "SOAPAction: \"\"";
而不是:
std::string strConnect = "Connection: close\r\n";
std::string strUserAgent = "User-Agent: gSOAP/2.7\r\n";
std::string strConnectionType = "Content-Type: text/html; charset=UTF-8;\r\n";
std::string strSoapAction = "SOAPAction: \"\"\r\n";
如果是上面加了\r\n的寫法,即便是調試發現報文頭裏還是有SOAPAction屬性的,但是不會起作用!!!(這個與我代碼對報文頭處理有關,具體怎麼寫不確定可以嘗試打印下格式,再調整)
【問題三】**
描述:發送報文後會報錯:
org.xml.sax.SAXParseException:lineNumber:1;columnNumber: 1;Content is not allowed in prolog.如下圖:
解決:網上找了資料發現是認爲是發送報文的開始
<?xml version="1.0" encoding="GBK"?>
- 前有空格,建議用notepad++打開修改編碼爲utf-8無BOM格式。嘗試後無效。
- 抓包分析對比報文格式,發現原因可能是自定義報文頭有換行或者空格造成,類似於問題二那種錯誤寫法,修改正確即可
【問題四】****
描述:發送報文後報錯:org.xml.sax.SAXException: SimpleDeserializer encountered a child element, which is NOT expected, in something it was trying to deserialize.如下圖:
過程:網上查找資料說是與不能反序列化有關,而且給出的方法基本都是java解決方案,如果有java的可以嘗試下,而我用的是c++,然後嘗試打通網絡(這是公司環境無法直接用工具測試,無奈配置了隧道纔可以)用soupui直接發送,查看報文格式
解決:最後對比發現程序發送報文與用工具直接發送報文內容一致,唯一不同的是工具發送會將報文用
<![CDATA[ XXXXX ]]>
抱起來,哦不,包起來(XXX爲報文內容)。最後修改代碼拼接報文格式,也將報文包起來,嘗試發送,問題解決!
提示
如果有類似我上述工作的操作,建議先採用curl命令直接發送報文,避免來回修改代碼編碼等等工作的繁瑣。同時如果也需要curl發送不驗證安全證書的話,需要加上-k參數,參考如下:
echo '<?xml version= "1.0" encoding="GBK"?>XX報文XX'|curl -k -X POST -H 'SOAPAction:\"\" Accept-Encoding: gzip,deflate User-Agent: gSOAP/2.7 Content-type:text/xml' -d @- https://111.111.111.111:8888/services/ABC?wsdl
如果環境無法直接執行curl命令。可以參考我的另一篇文章:
https://blog.csdn.net/Cow_cz/article/details/81128920