Send an image as a multi part File
Hello,
We would like some advice
We have developed a REST Operation
The code is:
Class Operaciones.REST.miSCS.miSCS Extends EnsLib.REST.Operation
{
Parameter INVOCATION = "Queue";
/// 📤 Subir la imagen del usuario
Method SubirImagen(pRequest As Mensajes.Request.miSCS.SubirImagen, pResponse As Mensajes.Response.miSCS.SubirImagen) As %Library.Status
{
set httpRequest = ##class(%Net.HttpRequest).%New()
set tResponse = ##class(%Net.HttpResponse).%New()
//set httpRequest.ContentType = "application/json"
set httpRequest.ContentType = "multipart/form-data"
set url = ##class(Util.TablasMaestras).getValorMaestra("MISCS.PARAMETRIZACIONES","url")
set path = ##class(Util.TablasMaestras).getValorMaestra("MISCS.PARAMETRIZACIONES","path")
set servicio = ##class(Util.TablasMaestras).getValorMaestra("MISCS.PARAMETRIZACIONES","servicio")
set recurso = ##class(Util.TablasMaestras).getValorMaestra("MISCS.PARAMETRIZACIONES","subirImagen")
set URL = "http://"_url_path_servicio_recurso
$$$LOGINFO("URL: "_URL)
/*
//Probamos a leer una imagen local y a enviarla
Set stream=##class(%Stream.FileCharacter).%New()
Set sc=stream.LinkToFile("Pictures\mi.jpg")
While 'stream.AtEnd {
Set linea=stream.Read()
}
$$$LOGINFO("linea: "_linea)
*/
set tFormVarNames = "expediente,imagen"
set tData("expediente") = pRequest.expediente
set tData("imagen") = pRequest.imagen
//set tData("imagen") = linea
set tSC = ..Adapter.SendFormDataArray(.tResponse,"POST",httpRequest,.tFormVarNames,.tData,URL)
$$$LOGINFO("tSC: "_tSC)
if $$$ISERR(tSC){
$$$ThrowOnError(tSC)
}
if (tResponse.Data.AtEnd = 0) {
$$$LOGINFO("En SubirImagen, tamaño de tResponse: "_tResponse.Data.Size)
set linea = tResponse.Data.Read()
$$$LOGINFO("Linea: "_linea)
}
set pResponse = ##class(Mensajes.Response.miSCS.SubirImagen).%New()
do pResponse.return.Write(linea)
Quit pResponse
}
XData MessageMap
{
<MapItems>
<MapItem MessageType="Mensajes.Request.miSCS.SubirImagen">
<Method>SubirImagen</Method>
</MapItem>
</MapItems>
}
When we send the request from the Production testing the Operation we get the following exception:
ERROR <Ens>ErrException: <THROW>zSubirImagen+27^Operaciones.REST.miSCS.miSCS.1 *%Exception.StatusException ERROR <Ens>ErrHTTPStatus: Received non-OK status 500 from remote HTTP server: 'HTTP/1.1 500 ' -- logged as '-' number - @' Set sc=tSC Throw:('sc) ##class(%Exception.StatusException).ThrowIfInterrupt(sc)'
Using POSTMAN directly to the endpoint we observe the following in Whireshark:
> As you would notice we see that the image is being sent as a multipart file, so then it is correct because the endpoint replies to us.
When we capture the request sent with Ensemble we see:
Here we observe that the image is being sent as text.
How could we send an image as a multi part File, using a REST Operation in Ensemble?
Could you help us? Could you provide some code example, please?
Thanks in advance
We have read:
https://docs.intersystems.com/latest/csp/docbook/Doc.View.cls?KEY=EREST_...
https://community.intersystems.com/post/polling-external-rest-api-ensemble
https://community.intersystems.com/post/how-send-file-json
https://community.intersystems.com/post/send-json-http-request
https://docs.intersystems.com/latest/csp/documatic/%25CSP.Documatic.cls?...
https://docs.intersystems.com/latest/csp/docbook/Doc.View.cls?KEY=GOBJ_p...
Here's a doc about creating multipart/form-data requests:
https://docs.intersystems.com/irisforhealthlatest/csp/docbook/DocBook.UI...
Hello,
Thanks Marc Mundt for your help,
1 We have tried with the following code which reads a String which represents an image in pRequest.imagen and we send it into a MIME:
However when we see it using Whireshark we observe that it is being sent as text/html
2 We have also used the following approach, to read a JPG directly and send it into the MIME:
With the previous code we see that a text/html is being sent too:
In both cases, the external system gives us a HTTP code 400:
ERROR <Ens>ErrException: <THROW>zSubirImagen+40^Operaciones.REST.miSCS.miSCS.1 *%Exception.StatusException ERROR <Ens>ErrHTTPStatus: Received non-OK status 400 from remote HTTP server: 'HTTP/1.1 400 ' -- logged as '-' number - @' Set sc=tSC Throw:('sc) ##class(%Exception.StatusException).ThrowIfInterrupt(sc)'
How could we achieve to send it in the correct way? as it is being sent when we use POSTMAN:
How could we send the image as multipart/form-data?
> We have read:
https://docs.intersystems.com/irisforhealthlatest/csp/docbook/DocBook.UI...
https://docs.intersystems.com/irisforhealthlatest/csp/docbook/Doc.View.c...
How could we send the image as multipart/form-data as it is being sent by Postman?
➡️ Could you point us to same code examples, please?
Hello,
We have continued the development,
The output system now replies to us
However we do see that the 2nd MIME part, the image, is being sent from ENSEMBLE, different than the image sent with POSTMAN
1 Let's see what we send from Ensemble:
2 The following image show us what POSTMAN correctly sends:
If we examine and compare both images, we observe that the image sent with Postam is being recognized as a JPEG, however the one sent with Ensemble is not being sent as a JPEG
The code which we have written is:
How could we continue‽
Could you point us to some example??, please
We have read:
https://docs.intersystems.com/irisforhealthlatest/csp/docbook/DocBook.UI...
Thanks in advance
Hi Yone,
I see two possible problems:
It seems like "Do ImagenMIMEPart.Body.Write(linea)" should be inside the while loop. No? In this case after the final read() linea may be empty and that is what is set as the content of the mime part.
While 'stream.AtEnd { Set linea=stream.Read() } $$$LOGINFO("linea: "_linea) //Escribir la imagen en el mensaje MIME Do ImagenMIMEPart.Body.Write(linea)
And here you are using a character stream to read the jpeg, but jpeg is a binary format. You'll want to use %Stream.FileBinary instead.
Set stream=##class(%Stream.FileCharacter).%New() Set sc=stream.LinkToFile("C:\Users\ext-ymorjim\Pictures\miSCS.jpg")
Hi,
Maybe this project can be useful/helpful to you.
https://openexchange.intersystems.com/package/upload-adapter