Web service how to return json data

Server:

Class webservice.SOAPResponse Extends (%RegisteredObject, %XML.Adaptor)
{

Property CustomerID As %String;

Property Name As %String;

Property Street As %String;

Property City As %String;

Property State As %String;

Property Zip As %String;

}

//--------------------

///
Class webservice.webServiceServer Extends %SOAP.WebService [ ProcedureBlock ]
{

Parameter SERVICENAME = "webServiceServer";

Parameter NAMESPACE = "http://tempuri.org";

Parameter USECLASSNAMESPACES = 1;

Method info(queryInfo As %String) As webservice.SOAPResponse [ WebMethod ]
{

    
    set soapresponse=##class(webservice.SOAPResponse).%New()
    set soapresponse.CustomerID="aaavca1"
    set soapresponse.Name="server:"_queryInfo
    set soapresponse.Street="aaaa3"
    set soapresponse.City="aaaccxaa4"
    set soapresponse.State="aaaszxaaa5"
    set soapresponse.Zip="aaaaazzaa6"
    quit soapresponse
}

/// return json
Method infoJson() As %String [ WebMethod ]
{
    
    set soapresponse=##class(webservice.SOAPResponse).%New()
    set soapresponse.CustomerID="1"
    set soapresponse.Name="2"
    set soapresponse.Street="3"
    set soapresponse.City="4"
    set soapresponse.State="5"
    set soapresponse.Zip="6"
    s result=""
    d ##class(%ZEN.Auxiliary.jsonProvider).%ObjectToJSON(soapresponse,.result,,"s")
    s resultinfo=result
    /// return null
    q resultinfo
}

}

/// ----------------------------------------------------------------------------------------

Client:

/// created: http://localhost:57772/dthealth/web/webservice.webServiceServer.CLS?WSDL=1
Class webServiceServer.SOAPResponse Extends (%RegisteredObject, %XML.Adaptor) [ ProcedureBlock ]
{

Parameter ELEMENTQUALIFIED = 1;

Parameter NAMESPACE = "http://tempuri.org";

Parameter XMLNAME = "SOAPResponse";

Parameter XMLSEQUENCE = 1;

Property CustomerID As %String(MAXLEN = "", XMLNAME = "CustomerID");

Property Name As %String(MAXLEN = "", XMLNAME = "Name");

Property Street As %String(MAXLEN = "", XMLNAME = "Street");

Property City As %String(MAXLEN = "", XMLNAME = "City");

Property State As %String(MAXLEN = "", XMLNAME = "State");

Property Zip As %String(MAXLEN = "", XMLNAME = "Zip");

}

//-------------------

Class webServiceServer.webclient.webServiceServerSoap Extends %SOAP.WebClient [ ProcedureBlock ]
{

/// This is the URL used to access the web service.
Parameter LOCATION = "http://localhost:57772/dthealth/web/webservice.webServiceServer.cls";

/// This is the namespace used by the Service
Parameter NAMESPACE = "http://tempuri.org";

/// Use xsi:type attribute for literal types.
Parameter OUTPUTTYPEATTRIBUTE = 1;

/// Determines handling of Security header.
Parameter SECURITYIN = "ALLOW";

/// This is the name of the Service
Parameter SERVICENAME = "webServiceServer";

/// This is the SOAP version supported by the service.
Parameter SOAPVERSION = 1.1;

Method info(queryInfo As %String) As webServiceServer.SOAPResponse [ Final, ProcedureBlock = 1, SoapBindingStyle = document, SoapBodyUse = literal, WebMethod ]
{
 Quit ..WebMethod("info").Invoke($this,"http://tempuri.org/webservice.webServiceServer.info",.queryInfo)
}

Method infoJson() As %String [ Final, ProcedureBlock = 1, SoapBindingStyle = document, SoapBodyUse = literal, WebMethod ]
{
 Quit ..WebMethod("infoJson").Invoke($this,"http://tempuri.org/webservice.webServiceServer.infoJson")
}

}

// ------------------------------------------------------------

Test:

Class PRD.Test Extends %RegisteredObject
{

///  d ##class(PRD.Test).testWebClient()
ClassMethod testWebClient()
{
    s obj = ##class(webServiceServer.webclient.webServiceServerSoap).%New()
    s val = obj.info("client")
    w val.CustomerID,!
    w val.Name,!
    w val.Street,!
    w val.City,!
    w val.State,!
    w val.Zip,!
}

/// test return json.
///  d ##class(PRD.Test).testWebClientJson()
ClassMethod testWebClientJson()
{
    s obj = ##class(webServiceServer.webclient.webServiceServerSoap).%New()
    s val = obj.infoJson()
    /// val is null
    w val,!
}

/// d ##class(PRD.Test).test1()
ClassMethod test1() As %String
{
    set soapresponse=##class(webservice.SOAPResponse).%New()
    set soapresponse.CustomerID="1"
    set soapresponse.Name="2"
    set soapresponse.Street="3"
    set soapresponse.City="4"
    set soapresponse.State="5"
    set soapresponse.Zip="6"
    s result=""
    s abc=##class(%ZEN.Auxiliary.jsonProvider).%ObjectToJSON(soapresponse,.result,,"s")
    /// result =  {"CustomerID":"1","Name":"2","Street":"3","City":"4","State":"5","Zip":"6"}
    q result
}

}

Comparing:

/// ok

/// d ##class(PRD.Test).test1()

ClassMethod test1() As %String
{
    set soapresponse=##class(webservice.SOAPResponse).%New()
    set soapresponse.CustomerID="1"
    set soapresponse.Name="2"
    set soapresponse.Street="3"
    set soapresponse.City="4"
    set soapresponse.State="5"
    set soapresponse.Zip="6"
    s result=""
    /// {"CustomerID":"1","Name":"2","Street":"3","City":"4","State":"5","Zip":"6"}
    s abc=##class(%ZEN.Auxiliary.jsonProvider).%ObjectToJSON(soapresponse,.result,,"s")
    q result
}

/// --- 

/// error
/// d ##class(webservice.webServiceServer).infoJson()
Method infoJson() As %String [ WebMethod ]
{   
    set soapresponse=##class(webservice.SOAPResponse).%New()
    set soapresponse.CustomerID="1"
    set soapresponse.Name="2"
    set soapresponse.Street="3"
    set soapresponse.City="4"
    set soapresponse.State="5"
    set soapresponse.Zip="6"
    s result=""
    d ##class(%ZEN.Auxiliary.altJSONProvider).%WriteJSONFromObject(,.result)
    s ^TMPPRD1=result
    s resultinfo=result
    q resultinfo
}

How can I modify it? Thank you!

  • 0
  • 0
  • 857
  • 3
  • 3

Answers

Make two changes to your code:

  1. /// return json
    Method infoJson() As %String WebMethod ]
    {
        set soapresponse=##class(webservice.SOAPResponse).%New()
        set soapresponse.CustomerID="1"
        set soapresponse.Name="2"
        set soapresponse.Street="3"
        set soapresponse.City="4"
        set soapresponse.State="5"
        set soapresponse.Zip="6"
    
        set stream=##class(%Stream.TmpBinary).%New()
        do ##class(%ZEN.Auxiliary.jsonProvider).%WriteJSONStreamFromObject(stream,soapresponse,,,$$$YES,"s")
        quit stream.Read($$$MaxStringLength)
    }
  2. /// write ##class(PRD.Test).test1()
    ClassMethod test1() As %String
    {
        set soapresponse=##class(webservice.SOAPResponse).%New()
        set soapresponse.CustomerID="1"
        set soapresponse.Name="2"
        set soapresponse.Street="3"
        set soapresponse.City="4"
        set soapresponse.State="5"
        set soapresponse.Zip="6"
        
        set stream=##class(%Stream.TmpBinary).%New()
        do ##class(%ZEN.Auxiliary.jsonProvider).%WriteJSONStreamFromObject(stream,soapresponse,,,$$$YES,"s")
        quit stream.Read($$$MaxStringLength)
    }

This method can be used, thank you!

I would suggest using JSON in another way.

If you caught some errors, please provide more details, sometimes it is quite difficult to predict whats going on, and it helps to find the solution faster.

If you doing SOAP, it should be XML. If you need JSON response it could not be SOAP, it can be REST.

Why did you use altJSONProvider  instead of jsonProvider

OK, then I try REST. I just don't know why returning JSON in a web service is invalid.

The issue is that following method:

##class(%ZEN.Auxiliary.jsonProvider).%ObjectToJSON(soapresponse,.result,,"s")

doesn't set variable result, but only writes out the contents of object instance soapresponse  to the current device using JSON notation, as you can find in %ZEN.Auxiliary.jsonProvider class documentation.

To output the content in JSON format I would recommend to use %DynamicObject and its %ToJSON() method:

/// return json
Method infoJson() As %String [ WebMethod ]
{
    set soapresponse=##class(%DynamicObject).%New()
    set soapresponse.CustomerID="1"
    set soapresponse.Name="2"
    set soapresponse.Street="3"
    set soapresponse.City="4"
    set soapresponse.State="5"
    set soapresponse.Zip="6"
    resultinfo=soapresponse.%ToJSON()
    resultinfo
}

It should help to retrieve JSON string.

Class webservice.SOAPResponse Extends (%RegisteredObject, %XML.Adaptor)
{

Property CustomerID As %String;

Property Name As %String;

Property Street As %String;

Property City As %String;

Property State As %String;

Property Zip As %String;

}
I tried this method,Why can't I use SOAPResponse to inherit %DynamicObject to generate json?