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;
...
ObjectScriptObjectScript
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 = "");
...
ObjectScriptObjectScript
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>
}
}
ObjectScriptObjectScript
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
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)
Expanding on this a little, your service / process that calls the operation will get back an Ens.StringContainer, if at this point you need access to the JSON then convert the stream to a dynamic object, something like...
set obj = ##class(%DynamicAbstractObject).%FromJSON(response.StreamGet())
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) }