Question
· Oct 23, 2023

What is the recommended way to convert a %Stream.Object to a Ens.Response message?

Hello,
First of all thanks for your help.

We have developed a REST Operation. We wonder how could we face that String do have a character limit.

We just need to convert httpRequest.HttpResponse , which is a stream , because $isobject(response.Data) returns 1; which has a JSON inside it, and we need to convert it to a Ens.Response.

This response is structured as same as the JSON's properties: 

   Class Mensajes.Response.Radiologia.CConcertados.BusquedaOrdenesNEGRINResponse Extends Ens.Response
    {

    Property data As list Of EsquemasDatos.CConcertadostoPACS.Radiologia.BusquedaOrdenes;

    ...

  

 Class EsquemasDatos.CConcertadostoPACS.Radiologia.BusquedaOrdenes Extends (%SerialObject, %XML.Adaptor)
    {

    Property "ID_SICH" As %String(MAXLEN = "");

    Property "FECHA_DERIVACION" As %String(MAXLEN = "");

    Property "MEDICO_PETICIONARIO" As %String(MAXLEN = "");

    ...

We have developed it as:
    

Class Operaciones.REST.Radiologia.CConcertadosOrdenesNEGRINv01r00 Extends EnsLib.REST.Operation
    {

    Parameter INVOCATION = "Queue";

    Method BusquedaOrdenes(pRequest As Mensajes.Request.Radiologia.CConcertados.BusquedaOrdenesNEGRINRequest, pResponse As Mensajes.Response.Radiologia.CConcertados.BusquedaOrdenesNEGRINResponse) As %Library.Status
    {
        //Creamos Request y Response HTTP
        Set httpRequest=##class(%Net.HttpRequest).%New()
        set tResponse = ##class(%Net.HttpResponse).%New()
        set claseAux = ##class(%ZEN.Auxiliary.jsonProvider).%New()

        set URL        = ..Adapter.URL

        set httpRequest.SSLConfiguration = ..Adapter.SSLConfig
            
        $$$LOGALERT("URL: "_URL)    

        // El body va relleno
        set httpRequestBody = ""
        
        //Convertimos el OBJETO devuelto por el Proceso en JSON
        set tSC = claseAux.%WriteJSONStreamFromObject(.pOutput,.pRequest,,,,"aeloqtuw")
        set json = pOutput.Read()
        
        do httpRequest.EntityBody.Write(json)    
        
        while (httpRequest.EntityBody.AtEnd = 0) {
            set httpRequestBody = httpRequest.EntityBody.Read()
        }    
        $$$LOGALERT("httpRequestBody: "_httpRequestBody)
        
        do httpRequest.EntityBody.Rewind()
            
        ;set tSC=httpRequest.Get(URL,0)
        set tSC=httpRequest.Post(URL,0)

        //Lanzamos excepcion si hubo error
        if $$$ISERR(tSC){
                $$$ThrowOnError(tSC)
        }

        //Obtenemos respuesta
        set tResponse = httpRequest.HttpResponse
        $$$LOGASSERT("httpRequest.HttpResponse.ContentLength: "_httpRequest.HttpResponse.ContentLength)
        $$$LOGALERT("$isobject(tResponse.Data): "_$isobject(tResponse.Data))

        ;set linea = ""
        ;set linea = ##class(%GlobalCharacterStream).%New()
        #dim dynamicobject as %Library.DynamicObject
        set dynamicobject = ##class(%Library.DynamicAbstractObject).%FromJSON(tResponse.Data)
        set json = dynamicobject.%ToJSON()
        $$$LOGINFO("json: "_json)
        
        //Leemos respuesta
        /*
        while (tResponse.Data.AtEnd = 0) {
            ;set linea = linea_$ZCONVERT(tResponse.Data.Read(),"I","UTF8")
            ;do linea.Write($ZCONVERT(tResponse.Data.Read(),"I","UTF8"))
            ;do linea.Write(tResponse.Data.Read())
            set linea = linea_tResponse.Data.Read()
        }
        */
        
        ;do linea.Rewind()
        ;$$$LOGINFO("linea.Read(): "_linea.Read())
        ;$$$LOGINFO("$LENGTH(linea): "_$LENGTH(linea))
        ;do linea.Rewind()
        ;$$$LOGINFO("linea: "_linea)
        
        // se transforma el objeto JSON a un objeto local
        ;set tSC= claseAux.%ConvertJSONToObject(linea,"Mensajes.Response.Radiologia.CConcertados.BusquedaOrdenesNEGRINResponse",.pResponse,1)    
        ;set tSC= claseAux.%ConvertJSONToObject(linea.Read(),"Mensajes.Response.Radiologia.CConcertados.BusquedaOrdenesNEGRINResponse",.pResponse,1)    
        set tSC= claseAux.%ConvertJSONToObject(json,"Mensajes.Response.Radiologia.CConcertados.BusquedaOrdenesNEGRINResponse",.pResponse,1)    
        
        ;$$$LOGINFO("Texto error: "_$System.Status.GetErrorText(tSC))
        
        //Rellenamos response
        
        ;set pResponse = ##class(Mensajes.Response.CConcertadostoPACS.Radiologia.BusquedaOrdenesNEGRINResponse).%New()
        ;set pResponse.data = json
        

        Quit pResponse
    }

    XData MessageMap
    {
    <MapItems>
      <MapItem MessageType="Mensajes.Request.Radiologia.CConcertados.BusquedaOrdenesNEGRINRequest">
        <Method>BusquedaOrdenes</Method>
      </MapItem>
      </MapItems>
    }

    }

Our worry is that the method "%ConvertJSONToObject" required a %String as first parameter, so it is being limited to the System's limits for Strings.

We wonder how could we just convert the %Stream.Object to structured Ens.Response, even if it is too big.

Could you help us please?

Thanks for your help

We have also read:

https://community.intersystems.com/post/maxlen-usage-strings

https://community.intersystems.com/post/convert-characterstream-json-and...

https://community.intersystems.com/post/maxstring-limit-issue

Discussion (3)2
Log in or sign up to continue

Hi Yone,

I would keep it simple, avoid unpacking JSON here and make pResponse a generic Ens.StreamContainer

Something like this should do it...

set tSC=httpRequest.Post(URL,0)
if $$$ISERR(tSC) return tSC  //no need to throw, the director will handle tSC
set pResponse=##class(Ens.StreamContainer).%New()
return pResponse.StreamSet(tResponse.Data)

Hello Yone,

Why don't you use %Stream.GlobalCharacter stream object to store  Long string instead of %String property. You can extend your class with %JSON.Adaptor and create a JSON object and directly import with your contents like below.

ClassMethod Import()
{
    set json=[{"ID_SICH":"121212","FECHA_DERIVACION":123,"MEDICO_PETICIONARIO":(tResponse.Data)}]
    set obj = ##Class(Mensajes.Response.Radiologia.CConcertados.BusquedaOrdenesNEGRINResponse).%New()
    set stt= o.%JSONImport(json)
    if $$$ISERR(stt) write $SYSTEM.OBJ.DisplayError(stt)
    set stt= obj.%Save()
    if $$$ISERR(stt) write $SYSTEM.OBJ.DisplayError(stt)
}