Article
· Feb 17 2m read

Importing json object with a large string property

For one of our customers I had to integrate with the AFAS imageconnector endpoint /imageconnector/{imageId}?format={format}.
This endpoint returns in a json message with the image as a base64-encoded string property, in addition to the mimetype for the image:

/// 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");
}

In the Message class, we tried handling this like:

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
}

This all worked fine until at some point the size of the filedata became larger than the $$$MaxStringLength (3641144), in which case a MAXSTRING exception was raised.

The logical next step was to change the type of the filedata property to %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");
}

But that didn't work, %JSONImport() would still raise a MAXSTRING error.

I then tried Python, but as I am not a python wizard, I gave up on that route eventually.

Thanks to the answer from https://community.intersystems.com/user/steven-hobbs on https://community.intersystems.com/post/maxstring-trying-read-string-jso..., I then learned that it is possible and straightforward to retrieve json string properties into a stream using 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
}

I am still puzzled as how I would be able to instruct the %JSON.Adaptor class and use the built-in logic to map to a stream.
If there is anyone out there that knows how to do this, please let me know!

Discussion (2)2
Log in or sign up to continue