Artigo
· Fev. 25 3min de leitura

Importando oum objeto json com uma propriedade de string grande

Para um de nossos clientes, precisei integrar com o endpoint AFAS imageconnector/imageconnector/{imageId}?format={format}.
Esse endpoint retorna uma mensagem JSON com a imagem como uma propriedade de string codificada em base64, além do mimetype da imagem.

/// Image Object
Class Mycustomer.Model.AfasGet.Image Extends (%SerialObject, %XML.Adaptor, %JSON.Adaptor)
{
/// file data (base64 encoded)
Property Filedata As %String(%JSONFIELDNAME = "filedata");

/// MimeType e.g. "image/jpeg"
Property MimeType As %String(%JSONFIELDNAME = "mimetype");
}

Na classe Message, tentamos lidar com isso da seguinte forma:

Property Image As Mycustomer.Model.AfasGet.Image;

/// AFAS GetImage response
/// 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
}

Tudo isso funcionava bem até que, em algum momento, o tamanho do filedata se tornou maior que o $$$MaxStringLength (3.641.144), caso em que uma exceção MAXSTRING era levantada.

O próximo passo lógico foi alterar o tipo da propriedade filedata para %Stream.GlobalCharacter:

/// Image Object
Class Mycustomer.Model.AfasGet.Image Extends (%SerialObject, %XML.Adaptor, %JSON.Adaptor)
{
/// file data (base64 encoded)
Property Filedata As %Stream.GlobalCharacter(%JSONFIELDNAME = "filedata");

/// MimeType e.g. "image/jpeg"
Property MimeType As %String(%JSONFIELDNAME = "mimetype");
}

Mas isso não funcionou, %JSONImport() ainda gerava um erro MAXSTRING

Tentei então com Python, mas como não sou um especialista em Python, eventualmente desisti dessa abordagem.

Graças à resposta de Steven Hobbs https://community.intersystems.com/user/steven-hobbs em https://community.intersystems.com/post/maxstring-trying-read-string-jso..., aprendi então que é possível e direto recuperar propriedades de string JSON para um stream usando 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
}

Ainda estou perplexo sobre como eu poderia instruir a classe %JSON.Adaptor e usar a lógica interna para mapear para um stream.
Se houver alguém por aí que saiba como fazer isso, por favor, me avise!

Discussão (0)1
Entre ou crie uma conta para continuar