Question
Yone Moreno · Jan 28, 2021

Send an image as a binary from a REST Service, as %Stream.GlobalBinary or %Stream.FileBinary;

Hello,

We would need some help,

Our aim is to send an image as binary data using a REST Service

Currently we do the following:

1 We get from the external system a binary image in our REST Operation

2 We encode it to Base64

set linea=""
    while (tResponse.Data.AtEnd = 0) {
        set linea = linea_$system.Encryption.Base64Encode(tResponse.Data.Read(57))
    }

3 We send it to the Process in a Response Message:

Class Mensajes.Response.miSCS.ConsultarImagen Extends Ens.Response
{

Property resultado As %Boolean;

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

Property binario As %Stream.GlobalBinary;

// Property binario As %Stream.FileBinary;

// Property binario As %GlobalCharacterStream;

// Property binario As %Stream.TmpCharacter;

Property error As EsquemasDatos.Seguridad.Error;

4 The Process takes kindly the Base64 and converts it into a Binary:

set binario = $system.Encryption.Base64Decode(response.informacion)
 
set response.informacion = binario

5 Our REST Service gets the Process response:

//Enviamos al Proceso
        #dim objetoSalida as Mensajes.Response.miSCS.ConsultarImagen
        set tSC = ..SendRequestSync("miSCS",objetoEntrada,.objetoSalida)

6 It writes the binary saved in "objetoSalida.informacion" to the binary property "objeto.binario"

 

       do objetoSalida.binario.Write(objetoSalida.informacion)

        $$$LOGINFO("objetoSalida.binario: "_objetoSalida.binario.Read())
        do objetoSalida.binario.Rewind()
        
        
        set objetoSalida.informacion = ""

7 Here comes the challenge:

When we convert the Object to JSON, it outputs "binario" the binary data, as "null":

set tSC = claseAux.%WriteJSONStreamFromObject(.pOutput,.objetoSalida,,,,"aeloqtuw")
        
        
$$$LOGINFO("pOutput.Read(): "_pOutput.Read())
do pOutput.Rewind()

 

When we observe the Message Viewer we see the following traces:

1 Before, we see objetoSalida.binario binary data, the image:

2 After, we observe it as null:

 

So then, in Postman we see it null:

 

 

How could we send an image as a binary from a REST Service?

 

We would need to send it as binary data, because if we return it as: %GlobalCharacterStream;

 

Postman would have the JPG image data with strange characters as "\x00" or "\x01"

 

Thanks for your help,

We have read:

https://community.intersystems.com/post/how-save-png-image-cache-base64-...

https://community.intersystems.com/post/decode-base64-file

https://community.intersystems.com/post/handling-images-cach%C3%A9-json-...

https://community.intersystems.com/post/binary-support-json

https://community.intersystems.com/post/sql-query-returns-x00

https://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY...

https://community.intersystems.com/post/stream-binary-json-work-around-h...

 

 

10
2 0 4 72

Replies

You are first copying the binary content into objetoSalida.informacion, which is a %String. Then you write the %String into objetoSalida.binario which is a %Stream.GlobalBinary.

Why not just make objetoSalida.binario a %String?

You could also make it %Binary instead of %String.

Thanks Marc Mundt for your help,

We have tried to make objetoSalida.binario as %Binary

Exactly we do the following:

1) We read the image as binary directly from the external system in the REST Operation:

set linea=""
    if (tResponse.Data.AtEnd = 0) {
        set linea = tResponse.Data.Read()
    }
    
    set pResponse.binario = linea
    
    $$$LOGINFO("pResponse.binario: "_pResponse.binario)

We observe the binary correctly written in the LOGINFO:

2) In the Service, we have a LOGINFO  before writing it to JSON

 $$$LOGINFO("objetoSalida.binario: "_objetoSalida.binario)        

 set tSC = claseAux.%WriteJSONStreamFromObject(.pOutput,.objetoSalida,,,,"aeloqtuw")

We see it correctly:

3) However when we convert it to JSON we see that there are strange characters like "\x00"

set tSC = claseAux.%WriteJSONStreamFromObject(.pOutput,.objetoSalida,,,,"aeloqtuw")

$$$LOGINFO("pOutput.Read(): "_pOutput.Read())

How would you recommend us to continue?

What documents or code examples would you study or write to handle this issue?

Thanks for your help

I suspect that some of the binary bytes are getting converted to UTF-8, and this is what the "u" option in the sixth argument of %WriteJSONStreamFromObject specifies.

You can try removing the "u" and see if that helps, but even if it does I believe you will find other problems because JSON isn't meant to carry raw binary data. Generally binary data is base 64 encoded when putting it in JSON.

One example of the problem with binary data is that the value of binario needs to be enclosed in quotes "". But the binary data could include a byte which is the same code as a quote, which would cause the JSON recipient to think that the value of binario has ended.

My suggestion is to base 64 encode the binary data.