Pour l'un de nos clients, j'ai dû intégrer le point de terminaison AFAS imageconnector /imageconnector/{imageId}?format={format}.
Ce point de terminaison renvoie un message json avec l'image comme propriété de chaîne codée en base64, en plus du type MIME de l'image :
/// Objet image
Class Mycustomer.Model.AfasGet.Image Extends (%SerialObject, %XML.Adaptor, %JSON.Adaptor)
{
/// données de fichier (encodées en base64)
Property Filedata As %String(%JSONFIELDNAME = "filedata");
/// MimeType par exemple "image/jpeg"
Property MimeType As %String(%JSONFIELDNAME = "mimetype");
}
Dans la classe Message, nous avons essayé de gérer cela comme :
Property Image As Mycustomer.Model.AfasGet.Image;
/// Réponse AFAS GetImage
/// get /imageconnector/{imageId}?format={format}
Method LoadFromResponse(httpResponse As %Net.HttpResponse, caller As %String = "") As %Status
{
Set sc = $$$OK
If $$$LOWER($Piece(httpResponse.ContentType,";",1))="application/json",httpResponse.StatusCode = "200" {
set ..Image = ##class(Mycustomer.Model.AfasGet.Image).%New()
set ..status = ..Image.%JSONImport(httpResponse.Data)
}
Return sc
}
Tout cela a bien fonctionné jusqu'à ce qu'à un moment donné, la taille des données du fichier devienne supérieure à $$$MaxStringLength (3641144), auquel cas une MAXSTRING exception a été levée.
L'étape logique suivante consistait à modifier le type de la propriété filedata en %Stream.GlobalCharacter :
/// Objet image
Class Mycustomer.Model.AfasGet.Image Extends (%SerialObject, %XML.Adaptor, %JSON.Adaptor)
{
/// Données de fichier (encodées en base64)
Property Filedata As %Stream.GlobalCharacter(%JSONFIELDNAME = "filedata");
/// Type Mime par exemple "image/jpeg"
Property MimeType As %String(%JSONFIELDNAME = "mimetype");
}
Mais cela n'a pas fonctionné, %JSONImport() générait toujours une erreur MAXSTRING.
J'ai ensuite essayé Python, mais comme je ne suis pas un expert en Python, j'ai finalement abandonné cette voie.
Grâce à la réponse de https://community.intersystems.com/user/steven-hobbs sur https://community.intersystems.com/post/maxstring-trying-read-string-jso..., j'ai alors appris qu'il est possible et simple de récupérer les propriétés de la chaîne json dans un flux en utilisant image.%Get("filedata", , "stream")):
Method LoadFromResponse(httpResponse As %Net.HttpResponse, caller As %String = "") As %Status
{
Set sc = $$$OK
If $$$LOWER($Piece(httpResponse.ContentType,";",1))="application/json",httpResponse.StatusCode = "200" {
set ..Image = ##class(Mycustomer.Model.AfasGet.Image).%New()
set image = {}.%FromJSON(httpResponse.Data)
set ..Image.MimeType = image.mimetype
set ..Image.Filedata = ##class(%Stream.GlobalCharacter).%New()
do ..Image.Filedata.CopyFrom(image.%Get("filedata", , "stream"))
}
Return sc
}
Je ne sais toujours pas comment je pourrais instruire la classe %JSON.Adaptor et utiliser la logique intégrée pour mapper vers un flux.
Si quelqu'un sait comment faire cela, faites-le moi savoir !