Page 1 of 1
JSON - request then decode
Posted: Mon Jul 17, 2017 10:19 pm
by TimStone
There was an discussion posted earlier that handled downloading a known JSON file and decoding it. Here is the code that was suggested:
Code: Select all
function Main()
local odoc := CreateObject( "MSXML2.DOMDocument" )
local ohttp := CreateObject( "MSXML2.XMLHTTP" )
local strret
ohttp:Open( "GET" ,"http://www.w3schools.com/angular/customers.php", .F. )
ohttp:SetRequestHeader( "Accept" , "application/xml")
ohttp:SetRequestHeader( "Content-Type" ,"application/json" )
oDoc:async := .f.
oDoc:LoadXml('<?xml version=""1.0"" encoding=""utf-8""?>')
ohttp:Send(oDoc:xml)
strret := alltrim(ohttp:responseText)
? strret
StrToHashArray( StrRet )
return nil
function StrToHashArray( cStr )
local hHash, aHash
cStr := CharRepl( "[]", RangeRem( 1, 31, cStr ), "{}" )
do while '" :' $ cStr
StrTran( cStr, '" :', '":' )
enddo
cStr := StrTran( cStr, '":', '"=>' )
hHash := &cStr
aHash := HGetValueAt( hHash, 1 )
xbrowser aHash setup ( obrw:autofit(), oBrw:bRClicked := { |r,c,f,o| o:ToDbf( "download.dbf", nil, nil, .t. ) } )
return nil
My problem is a bit different. I need to send a request to a defined website, and then read the result.
The sending statement is in the format:
Code: Select all
oHttp:=TIpClientHttp():new("https://testserver.com/data/1", .F. )
cJson := '{"partid":"147A964","productDataid":"PR123","locationid":"10000"}'
cRet := ""
IF .NOT. oHttp:open()
MsgAlert( "Connection error:", oHttp:lastErrorMessage( ) )
ELSE
oHttp:Post( cJson)
cRet := oHttp:readAll( )
oHttp:close()
ENDIF
nFileHandle := FCreate( "retdata.txt" )
FWrite( nFileHandle, cRet )
FClose( nFileHandle )
And the response should be a JSON string. However, I get no data back. I'll worry about parsing the data when I get a return string, but at this point, it appears JSON may not like the TIP Harbour control. With the example posted on JSON decoding previously, the approach was a bit different. I'd appreciate it if someone has some alternative approaches on how I should be handling this request / response sequence.
Thanks so much.
Tim
For XML data I have been using
Re: JSON - request then decode
Posted: Tue Jul 18, 2017 4:47 am
by anserkk
Code: Select all
oHttp:= CreateObject("Microsoft.XMLHTTP")
cUrl = "https://testserver.com/data/1"
oHttp:Open( "PUT", cUrl, .F.)
oHttp:setRequestHeader( "Content-type", "text/json" )
cJson := {"partid":"147A964","productDataid":"PR123","locationid":"10000"}
// Try the next line too, I am not sure.
// cJson := '{"partid":"147A964","productDataid":"PR123","locationid":"10000"}'
oHttp:Send(cJson)
? oHttp:Status
? oHttp:StatusText
? oHttp:responseText
Re: JSON - request then decode
Posted: Tue Jul 18, 2017 3:26 pm
by TimStone
It returns Status 405, StatusText "Method not allowed" and there is no response text.
A web search showed that this will occur if the JSON server does not accept PUT and requires a GET. So I made that change.
Now I get 415 Unsupported media type ....
Tim
Re: JSON - request then decode
Posted: Tue Jul 18, 2017 10:22 pm
by TimStone
Based on what the company says, and your method, here is the function code:
Code: Select all
FUNCTION ViewCFXServices3( )
LOCAL oHttp := CreateObject("Microsoft.XMLHTTP")
LOCAL cUrl := "https://testserver.com/data/1"
oHttp:Open( "POST", cUrl, .F.)
ohttp:SetRequestHeader( "Accept", "application/json")
oHttp:setRequestHeader( "Content-type", "applicationn/json" )
cJson := '{"partID":"ABC123","productDataId":"CAT001","locationId":"10000"}'
oHttp:Send(cJson)
? oHttp:Status
? oHttp:StatusText
? oHttp:responseText
RETURN NIL
Using the ARC add in for Google Chrome, the cJson string sent to that server with "application/json" does return the data.
Using this method, the status is 415, the StatusText is "Unsopported Media Type", and there is no responseText
Thoughts from ANYONE on where I go from here ?
Tim
Re: JSON - request then decode
Posted: Wed Jul 19, 2017 4:25 am
by anserkk
Please try the following code.
Please note that depending on the documentation from your Web-api service provider, you may have to change the values in the variable cContentType. Depending on the documentation, you may also have to try using GET, PUT, POST methods while opening the URL. For me POST is working fine to send a JSON content to one of my servers and the server is returning me response in JSON format. I believe that it depends on how the Server is configured, not sure. If the server requires authentication, then that too should be dealt with. Provision for Authorization is also there in the sample code that I have provided. I assume that the URL
https://testserver.com/data/1 is a dummy. When I tried that URL it is giving me 404 error.
Code: Select all
#include "Fivewin.ch"
//----------------------------------//
Function Main()
LOCAL aHash := hash()
LOCAL cJson,cContentType:="",cAuthorization:=""
ahash["partID"] = "ABC123"
ahash["productDataId"] = "CAT001"
ahash["locationId"] = "10000"
cJson := hb_jsonEncode(ahash,.f.)
cContentType:="application/json"
SendPostToUrl( "https://testserver.com/data/1", cJson, cContentType, cAuthorization )
Return
//---------------------------------------------------------------------//
Function SendPostToUrl( cUrl, cParams,cContentType,cAuthorization )
Local oOle,cRet:='',uRet
default cContentType:="application/x-www-form-urlencoded"
default cAuthorization:=""
Try
oOle := CreateObject( 'MSXML2.XMLHTTP' )
Catch
oOle := CreateObject( 'Microsoft.XMLHTTP' )
End
oOle:Open( 'POST', cUrl, .f. )
oOle:SetRequestHeader( "Content-Type",cContentType)
if !empty(cAuthorization)
oOle:SetRequestHeader( "Authorization",cAuthorization)
end if
oOle:Send( cParams )
SysRefresh()
#ifdef __XHARBOUR__
cRet := oOle:ResponseBody
#else
MsgInfo(oOle:ResponseBody)
cRet:=""
hb_jsonDecode(oOle:ResponseBody,@cRet)
xbrowser cRet
#endif
Return cRet
Regards
Anser
Re: JSON - request then decode
Posted: Wed Jul 19, 2017 5:01 am
by TimStone
If you send me your email to tim at gtstone dot com I can send you the actual values to use.
Re: JSON - request then decode
Posted: Wed Jul 19, 2017 9:48 am
by Patrizio
TimStone wrote:It returns Status 405, StatusText "Method not allowed" and there is no response text.
A web search showed that this will occur if the JSON server does not accept PUT and requires a GET. So I made that change.
Now I get 415 Unsupported media type ....
Tim
I got the same error with an asynchronous webservice, did you try to put such a cycle between the send and the responsetext?
Code: Select all
DO WHILE oXMLHttp:readyState <> 4
SysRefresh()
ENDDO
Re: JSON - request then decode
Posted: Wed Jul 19, 2017 12:43 pm
by anserkk
TimStone wrote:If you send me your email to tim at gtstone dot com I can send you the actual values to use.
anserkk at gmail.com
I am away from my work computer, may be I can try it out tomorrow.
Re: JSON - request then decode
Posted: Wed Jul 19, 2017 7:14 pm
by TimStone
Yes, I did try putting in a delay before looking at the response, but that does not help.
I should note that I building this with FWH 17.06, Harbour, and MSVC++ 2017.
For XML I am using tIPHTTPClient class with no problems, but JSON seems to be unhappy ....
Tim
Re: JSON - request then decode RESOLVED
Posted: Wed Jul 19, 2017 8:47 pm
by TimStone
OK ... so after all that, the process is actually quite simple, except when I added an extra n to the word application when stating the header setting for content.
Now I'm successfully implementing the call and receiving the data. I only looked at that for hours and did not see the spelling error.
Tim