Artigo
· jan 11 3min de leitura

Recuperando arquivos em Base64 de uma chamada POST evitando erros <MAXSTRING>

Sejam todos bem-vindos!

Neste breve artigo, quero apresentar um exemplo de uso que vários de vocês que trabalham com o IRIS como back-end para seus web applications devem ter enfrentado mais de uma vez: como enviar um arquivo do front-end para o servidor.

Em geral, a maneira mais simples que encontrei de realizar essa tarefa é transformar o arquivo do front-end para o formato Base64 e fazer uma chamada POST para o servidor anexando o Base64 obtido a uma mensagem JSON onde é indicado o nome do arquivo em um parâmetro e os dados codificados em outro. Algo parecido com isto:

{
    "fileData": "JVBERi0xLjQKJdPr6eEKMSAwIG...",
    "fileName": "example.pdf"
}

Da minha instância IRIS, configurei um web application para gerenciar essas chamadas POST de uma classe que estende %CSP.REST. Essa classe tem um classmethod para gerenciar o POST corretamente. O código deve ficar assim:

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
        // Lendo o corpo da chamada http com os dados do arquivo
        
        set 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
}

Vamos explicar em detalhes o que esse método está fazendo:

  1. Recebemos o conteúdo enviado no corpo da mensagem e transformamos isso em um %Library.DynamicAbstractObject que pode ser lido como um objeto.
    set dynamicBody = {}.%FromJSON(%request.Content)

     

  2. Essa etapa é onde a mágica acontece. Transformamos nosso Base64 em um tipo %Stream que podemos obter usando o método %Get da classe %Library.DynamicObject.
  3. set dynamicStream = dynamicBody.%Get("fileData",,"stream<base64")

    Como você pode ver, estamos passando como um parâmetro de entrada o tipo de transformação que queremos realizar, em nosso exemplo de Base64 para Stream (stream<base64). Qual é a vantagem de usar essa instrução? Bem, não vamos estar limitados pelo valor MAXSTRING, ou seja, se nosso arquivo em Base64 for muito grande, nunca vamos receber uma exceção porque ultrapassamos o limite máximo de comprimento permitido para uma String.

  4. Por fim, criamos em nosso servidor o arquivo que conterá os dados enviados em Base64 com o nome definido na chamada recebida e escrevemos nosso objeto de tipo %Stream nele.
    set stream=##class(%Stream.FileBinary).%New()
    set sc=stream.LinkToFile("/shared/durable/"_dynamicBody.fileName)
    set sc=stream.CopyFromAndSave(dynamicStream)

Como você pode ver, é muito fácil gerenciar arquivos em Base64 do nosso servidor. Se você tiver dúvidas, não hesite em escrevê-las na seção de comentários. Será um prazer responder.

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