parsing xml response
Hello!
I'm sending http resuest to the web service :
Set httpRequest=##class(%Net.HttpRequest).%New()
Set httpRequest.Server="177.127.120.10"
Set httpRequest.ContentType="text/xml"
Set httpRequest.Https=1
Set httpRequest.ContentCharset="UTF-8"
Do httpRequest.SetHeader("Accept","text/xml")
Set httpRequest.Timeout=300
Set xml="<CheckContractRequest><IIN>"_IINPay_"</IIN>"
_"<FirstName>"_name_"</FirstName>"
_"<LastName>"_surname_"</LastName>"
_"<MiddleName>"_middlename_"</MiddleName>"
_"<BirthDate>"_birthDate_"</BirthDate>"
_"<ContractType>CONST</ContractType></CheckContractRequest>"
do httpRequest.EntityBody.Write(xml)
set httpResponse = ##class(%Net.HttpResponse).%New()
Set httpResponse = httpRequest.Post("/sample/", 2)
set resp=httpRequest.HttpResponse
zw resp
if $zObjState(httpRequest.HttpResponse)
{
s resp=httpRequest.HttpResponse.Data
s len=32767,resptext=""
if $isObject(httpRequest.HttpResponse.Data) {
for {
q:httpRequest.HttpResponse.Data.AtEnd
s resptext=resptext_httpRequest.HttpResponse.Data.Read(.len) q:len<0
}
s ^tk(2)=resptext
s response=..getXMLValue(resptext, "message")
}
elseif ($l(resp.Data)>0 ) {
s resptext=resp.Data
}
}
response:
<CheckContractRequest>
<IIN>891299300335</IIN>
<FirstName>Ivan</FirstName>
<LastName>Ivanov</LastName>
<MiddleName>Ivanovich</MiddleName>
<BirthDate>01.01.1987</BirthDate>
<ContractType>CONST</ContractType>
</CheckContractRequest>
The response :
<?xml version="1.0" encoding="UTF-8"?>
<CheckContractResponse>
<code>0</code>
<message>OK</message>
</CheckContractResponse>
the question:
1) how to know that request was sent succesfully to web service?
how I can get data from stream bellow ?
resp=<OBJECT REFERENCE>[121@%Net.HttpResponse]
+----------------- general information ---------------
| oref value: 121
| class name: %Net.HttpResponse
| reference count: 3
+----------------- attribute values ------------------
| ContentBoundary = ""
| ContentInfo = ""
| ContentLength = ""
| ContentType = ""
| Data = "122@%Stream.GlobalBinary"
| HttpVersion = ""
| ReasonPhrase = ""
| StatusCode = ""
| StatusLine = ""
Comments
Usually response does contain status information in StatusCode and StatusLine properties.
You need to change this line
Set httpResponse = httpRequest.Post("/sample/", 2)to
#dim sc As %Status = $$$OK
Set sc = httpRequest.Post("/sample/", 2)Write $System.Status.GetErrorText(sc)As Post method returns status.
After debugging you can use
write $$$ISERR(sc)
macro to check if result of some operation is an error.
Hi Eduard!
Thank you for your response. I have change the code, method return output status=0.
I have sent the request using Postman utility and receive the response after 30 seconds.
how i can know that request was sent sussecfully and how to get readable response? Thank you.
Compare output of
Set sc = httpRequest.Post("/sample/", 1)with what Postman sends.
Also, what does
Set sc = httpRequest.Post("/sample/")
zw scshow?
Set sc = httpRequest.Post("/sample/", 1)The output:
set sc=##class(Example.TEST).xmlRequest("891208300335","Ivan","Ivanov","Ivanovich","08.12.1989","ОПВ")
POST /sample/ HTTP/1.1
User-Agent: IBM-APIConnect/5.0
Host: 172.27.139.151
Accept-Encoding: gzip
Accept: text/xml
x-ibm-client-id: adsad-adsadsa-asdsad
x-ibm-client-secret: 13213213asdsadsadsad
Content-Length: 251
Content-Type: text/xml; charset=UTF-8
<CheckContractRequest><IIN>891208300335</IIN><FirstName>Ivan</FirstName>
<LastName>Ivanov</LastName><MiddleName>Ivanovich</MiddleName>
<BirthDate>08.12.1989</BirthDate><ContractType>ОПВ</ContractType></CheckContractRequest>0
Set sc = httpRequest.Post("/sample/", 2)
zw scoutput: sc=1
When you get sc=1 , what about:
set resp=httpRequest.HttpResponsezw resp do resp.Data.OutputToDevice()
sc=1
0
resp=<OBJECT REFERENCE>[138@%Net.HttpResponse]
+----------------- general information ---------------
| oref value: 138
| class name: %Net.HttpResponse
| reference count: 3
+----------------- attribute values ------------------
| ContentBoundary = ""
| ContentInfo = ""
| ContentLength = ""
| ContentType = ""
| Data = "139@%Stream.GlobalBinary"
| HttpVersion = ""
| ReasonPhrase = ""
| StatusCode = ""
| StatusLine = ""
Interesting. Check this article - I think you'll need either HTTP Debugging proxy (probably) or Packet analyzer (maybe) to debug this further.
As you have reference implementation (Postman) you can start by comparing Postman request/response and Ensemble request/response using HTTP Debugging proxy.
Hello Eduard!
Now I'm getting error: 415 Unsupported Media Type. In the code i set:
Do httpRequest.SetHeader("accept","text/xml")
Set httpRequest.ContentType="text/xml"
HTTP/1.1 415 Unsupported Media Type
ACCESS-CONTROL-ALLOW-CREDENTIALS: false
ACCESS-CONTROL-ALLOW-METHODS: POST
ACCESS-CONTROL-ALLOW-ORIGIN: *
ACCESS-CONTROL-EXPOSE-HEADERS: APIm-Debug-Trans-Id, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-Global-Transaction-ID
CONNECTION: Keep-Alive
CONTENT-ENCODING: gzip
CONTENT-TYPE: text/plain
DATE: Thu, 13 Sep 2018 13:55:03 GMT
TRANSFER-ENCODING: chunked
USER-AGENT: IBM-APIConnect/5.0
X-BACKSIDE-TRANSPORT: OK OK
X-GLOBAL-TRANSACTION-ID: 2956707581
Unsupported Media Type
str=<OBJECT REFERENCE>[19@%Stream.FileCharacterGzip]
+----------------- general information ---------------
| oref value: 19
| class name: %Stream.FileCharacterGzip
| %%OID: $lb("C:\InterSystems\Ensemble2016\mgr\Temp\VqdL7hXdFahzDg.http","%Stream.FileCharacterGzip","")
| reference count: 3
+----------------- attribute values ------------------
| (%Concurrency) = 1
| %Location = "" <Set>
| (%LockRef) = ""
| (%Locked) = 0
| AtEnd = 0
| BOM = ""
| (CurrFile) = ""
| Id = "C:\InterSystems\Ensemble2016\mgr\Temp\VqdL7hXdFahzDg.http" <Set>
| LineTerminator = $c(13,10) <Set>
| (MakePermLoc) = 0
| (Mode) = 1
|(NormalizedDirectory) = "C:\InterSystems\Ensemble2016\mgr\Temp\"
|(OidTranslateTable) = "RAW"
| (ReadMode) = 0
| ReadSize = 48
| RemoveOnClose = 1
| (StoreFile) = "VqdL7hXdFahzDg.http"
| StreamFormatWrite = 1
| (TempFile) = ""
| TranslateTable = "RAW" <Set>
| UseVMSVersion = 0
| (VariableRecord) = 0
Try application/xml instead of text/xml for content type.
If it does not help, check API docs for correct type.
For accept try */*.
compare headers between postman and cache I found the difference in content type.
In postman : Content-Type: text/xml
In cache: Content-Type: text/xml; charset=UTF-8
How I can remove charset=UTF-8 from header in cache ?
Check NoDefaultContentCharset property in request.
Thanks a lot Eduard! It's working. But another problem has occured: the response is non readable:
<?xml version="1.0" encoding="UTF-8"?>
<CheckContractResponse><code>-1</code><message>ÐевеÑнÑй Ñип договоÑа</message></CheckContractResp>
As a direct solution you can do
write $zcvt("<CheckContractResponse><code>-1</code><message>ÐевеÑнÑй Ñип договоÑа</message></CheckContractResp>","I","UTF8")
<CheckContractResponse><code>-1</code><message>Неверный тип договора</message></CheckContractResp>