Json request

Primary tabs

Hello,

while sending JSON request :

Set Object = ##class(%ZEN.proxyObject).%New()
Set Object.iin="123132132"
Set Object.firstName=name
Set Object.lastName=surname
Set Object.middleName=middlename
Set Object.birthDate=birthDate
Set Object.contractType="Z001"

set sc = ##class(%ZEN.Auxiliary.jsonProvider).%ObjectToJSON(Object)

Set sc = ##class(%ZEN.Auxiliary.jsonProvider).%WriteJSONStreamFromObject(httpRequest.EntityBody, Object)

Set sc = httpRequest.Post("", 2)

receive error bellow:

"Corrupt body: json: cannot unmarshal number into Go struct field CheckContractRequest.iin of type string". 

how i can solve this problem, could anyone help.

the version of ensemble - 2010.1.2

  • + 1
  • 0
  • 364
  • 17
  • 1

Answers

Minor note, you don't need this line, remove it (it may be causing your error):

set sc = ##class(%ZEN.Auxiliary.jsonProvider).%ObjectToJSON(Object)

"Corrupt body: json: cannot unmarshal number into Go struct field CheckContractRequest.iin of type string". 

Where you get this error? This looks like an error you get from the server you send your request to.

Can you get output from

Set sc = httpRequest.Post("", 1) 

Set sc = httpRequest.Post("", 2)

And post it here.

remove the line, but still getting error:

httpResponse="Corrupt body: json: cannot unmarshal number into Go struct field CheckContractRequest.iin of type string"

HTTP/1.1 400 Bad Request
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: Tue, 14 Aug 2018 13:45:21 GMT
TRANSFER-ENCODING: chunked
X-BACKSIDE-TRANSPORT: OK OK
X-GLOBAL-TRANSACTION-ID: 647439117

Can you show the request itself via:

Set sc = httpRequest.Post("", 1) 

set sc=##class(Example.TEST).Check(901205300353,"Ivan","Ivanov","Ivanovich","05.12.1990","Z")                                                    
User-Agent: IBM-APIConnect/5.0
Host: 127.0.0.1
Accept-Encoding: gzip
x-ibm-client-id: test
x-ibm-client-secret: test
Content-Length: 180
Content-Type: application/json; charset=utf-8
 
{
        "birthDate":"05.12.1990",
        "contractType":"Z",
        "firstName":"Ivan",
        "iin":901205300353,
        "lastName":"Ivanov",
        "middleName":"Ivanovich"
}1POST /test/ HTTP/1.1

Is

1POST /test/ HTTP/1.1 

actually a part of the request body?

If so, it's invalid json and you need to remove it from request body. What does

do httpRequest.EntityBody.OutputToDevice()

shows right before  sending the request?

Other thought, iin property should be passed as string, not as number. To do that:

1. Create a class

Class MyApp.Request Extends %RegisteredObject {

Property iin As %String;

... other properties ...

}

2. After that instead of %ZEN.proxyObject use this object as a request body.

Note that %ZEN.Auxiliary.jsonProvider:%WriteJSONStreamFromObject method has a pFormat argument, which defaults to aceloqtw in %ObjectToJSON method. One of the flags, q  means  output numeric values unquoted even when they come from a non-numeric property and you don't need that.

So your code should look something like this:

Set Object = ##class(MyApp.Request).%New()
Set Object.iin="123132132"
Set Object.firstName=name
Set Object.lastName=surname
Set Object.middleName=middlename
Set Object.birthDate=birthDate
Set Object.contractType="Z001"
Set sc = ##class(%ZEN.Auxiliary.jsonProvider).%WriteJSONStreamFromObject(httpRequest.EntityBody, Object, , , , "aelotw")
Set sc = httpRequest.Post("", 2)

Thanks a lot Eduard!

Could you say how to parse JSON response in my case?

the response:

{

    "code": 0,

    "message": "OK"

}

Try:

set st = ##class(%ZEN.Auxiliary.jsonProvider).%ConvertJSONToObject(responseStream,,.obj,1)

obj would become %ZEN.proxyObject. You can also create a class and parse json into object of that class.

Hi Eduard!

still didn't parse the response.  Here is my code, can you help please?

Set httpResponse=httpRequest.HttpResponse.Data

Set sc = ##class(%ZEN.Auxiliary.jsonProvider).%ConvertJSONToObject(httpResponse,,.Object,1)

Check that stream is an object and contains relevant data:

write $isObject(httpResponse)

what data does it contain:

do httpResponse.OutputToDevice()

if it's not an object - what is it?

zwrite httpResponse

If everything is okay - stream contains what you expect it to contain, then what is the status of convert operation:

Set sc = ##class(%ZEN.Auxiliary.jsonProvider).%ConvertJSONToObject(httpResponse,,.Object,1)

write $System.Status.GetErrorText(sc)
zwrite Object

You seem to receive empty response.

What does

set resp = httpRequest.HttpResponse
zwrite resp
write !,!,!
do resp.OutputToDevice()

Output?

Forgot to mention that I added ClassMethod %ConvertJSONToObject to %ZEN.Auxiliary.jsonProvider. Is it correct ?

the response is empty: resp=""

I check the code in cache version2016 . 

When set property

Set httpRequest.SSLCheckServerIdentity=0, 

the response was successfull :

HTTP/1.1 200 OK
ACCESS-CONTROL-ALLOW-CREDENTIALS: false
ACCESS-CONTROL-ALLOW-METHODS: POST
ACCESS-CONTROL-ALLOW-ORIGIN: *
ACCESS-CONTROL-EXPOSE-HEADERS: 
CONNECTION: Keep-Alive
CONTENT-ENCODING: gzip
CONTENT-TYPE: application/json
DATE: Thu, 23 Aug 2018 03:31:32 GMT
TRANSFER-ENCODING: chunked
USER-AGENT: IBM-APIConnect/5.0
X-BACKSIDE-TRANSPORT: OK OK
X-GLOBAL-TRANSACTION-ID: 699524573
 
{"code":0,"message":"OK"}
httpResponse="{""code"":0,""message"":""OK""}"

You should not modify system classes.

So without

Set httpRequest.SSLCheckServerIdentity=0 

it doesn't work?

Well, updating to a newer version is definetly recommended.

This feature (SSLCheckServerIdentity) appeared in 2013.2.

That said, comments to the feature state that the new default is to check the name where as before we did not perform this check.

So on older version request should be working by default. What error are you getting on old version?