Récupération de fichiers Base64 à partir d'une requête POST en évitant les erreurs <MAXSTRING>
Bienvenue à tous!
Dans ce court article, je voudrais présenter un exemple d'utilisation auquel beaucoup d'entre vous qui travaillent avec IRIS comme backend pour vos applications Web ont sûrement été confrontés à plus d'une occasion : comment envoyer un fichier à votre serveur depuis le frontend. .
Généralement, le moyen le plus simple que j'ai trouvé pour effectuer cette tâche est de transformer le fichier du frontend au format Base64 et de faire un appel POST à notre serveur en attachant le Base64 obtenu à un message JSON dans lequel j'indique dans un paramètre le nom du fichier et dans un autre les données codées. Quelque chose de similaire à ceci :
{
"fileData": "JVBERi0xLjQKJdPr6eEKMSAwIG...",
"fileName": "example.pdf"
}Depuis mon instance IRIS, j'ai une application Web configurée pour gérer ces appels POST à partir d'une classe qui étend %CSP.REST. Cette classe possède une méthode de classe pour gérer correctement le POST. Le code ressemble à ceci :
ClassMethod SaveFile() As%Status
{
Try {
Do##class(%REST.Impl).%SetContentType("application/json")
If '##class(%REST.Impl).%CheckAccepts("application/json") Do##class(%REST.Impl).%ReportRESTError(..#HTTP406NOTACCEPTABLE,$$$ERROR($$$RESTBadAccepts)) Quit// Reading the body of the http call with the file dataset dynamicBody = {}.%FromJSON(%request.Content)
set dynamicStream = dynamicBody.%Get("fileData",,"stream<base64")
set stream=##class(%Stream.FileBinary).%New()
set sc=stream.LinkToFile("/shared/durable/"_dynamicBody.fileName)
set sc=stream.CopyFromAndSave(dynamicStream)
} Catch (ex) {
Do##class(%REST.Impl).%SetStatusCode("400")
Do##class(%REST.Impl).%WriteResponse(ex.DisplayString())
return {"errormessage": "Client error"}
}
Quit$$$OK
}Expliquons en détail ce que fait cette méthode :
- Nous récupérons le contenu envoyé dans le corps du message et le transformons en %Library.DynamicAbstractObject que nous pouvons lire en tant qu'objet.
set dynamicBody = {}.%FromJSON(%request.Content) - C'est dans cette étape que la magie opère, nous transformons notre Base64 en un type %Stream que nous pouvons obtenir en utilisant la méthode %Get de la classe %Library.DynamicObject.
-
set dynamicStream = dynamicBody.%Get("fileData",,"stream<base64")Comme vous pouvez le voir, nous passons en paramètre d'entrée le type de transformation que nous souhaitons effectuer, dans notre exemple de Base64 vers Stream (stream<base64). Quel est l’avantage d’utiliser cette instruction ? Eh bien, nous ne serons pas limités par la valeur MAXSTRING, c'est-à-dire que si notre fichier Base64 est très volumineux, nous ne recevrons jamais d'exception car nous avons dépassé la limite maximale de longueur autorisée pour une chaîne.
- Enfin, nous créons sur notre serveur le fichier qui contiendra les données envoyées en Base64 avec le nom défini dans l'appel reçu et nous y écrivons notre objet de type %Stream.
set stream=##class(%Stream.FileBinary).%New() set sc=stream.LinkToFile("/shared/durable/"_dynamicBody.fileName) set sc=stream.CopyFromAndSave(dynamicStream)
Comme vous pouvez le constater, il est très simple de gérer les fichiers Base64 depuis notre serveur. Si vous avez des questions, n'hésitez pas à les écrire dans la section commentaires, je me ferai un plaisir d'y répondre.