Article
· Fév 19 3m de lecture

Importer un objet JSON avec une grande string

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 !

Discussion (0)1
Connectez-vous ou inscrivez-vous pour continuer