JSON Serialization and Deserialization
This page documents the JSON serialization and deserialization system within the Mesh Connect Android SDK. The system handles conversion between JSON messages received from web content and strongly-typed Kotlin data classes used throughout the native Android code.
For information about the specific data models and payload structures, see Data Models. For details about the message broadcasting system that uses these converters, see Message Broadcasting System.
Overview
The SDK uses a centralized JSON conversion system built around the JsonConverter class to handle bidirectional conversion between JSON strings and Kotlin objects. This system is primarily used for:
- Deserializing messages received from embedded web content via the JSBridge
- Converting typed Kotlin objects back to JSON for web communication
- Type-safe handling of different message types based on JSON structure
Core Components
JsonConverter Class
The JsonConverter serves as the central conversion utility, providing methods for both serialization and deserialization operations. Based on the usage patterns in the codebase, it provides the following key methods:
fromJson(json: String, classOfT: Class<T>): T- Deserializes JSON to typed objectstoMap(json: String): Map<String, Any>- Converts JSON to key-value pairs for flexible access
Type-Based Message Processing
The system uses a type-based approach to determine how to deserialize incoming JSON messages. Each message contains a type field that maps to the Type enum:
| Type | Purpose | Target Class |
|---|---|---|
brokerageAccountAccessToken |
Account access tokens | AccessTokenPayload |
transferFinished |
Transfer completion | TransferFinishedPayload |
delayedAuthentication |
Delayed auth flow | DelayedAuthPayload |
error |
Error messages | JsError |
close |
Close events | Simple event |
done |
Done events | Simple event |
showClose |
Show close button | Simple event |
loaded |
Content loaded | Simple event |
openTrueAuth |
Open authentication | Link extraction |
Deserialization Flow
Message Type Detection and Routing
Raw JSON Message
JsType Deserialization
Extract type field
Type-based routing
Type.brokerageAccountAccessToken
Type.transferFinished
Type.delayedAuthentication
Type.error
Simple event types
Type.openTrueAuth
AccessTokenResponse
TransferFinishedResponse
DelayedAuthResponse
JsError
Link extraction via toMap()
AccessTokenPayload
TransferFinishedPayload
DelayedAuthPayload
LinkEvent.Payload
throw IllegalStateException
LinkEvent.TrueAuth
LinkEvent.Close/Done/etc
Payload Deserialization Process
Kotlin Objects
Deserialization Steps
JSON Structure
JSON Message
type: 'brokerageAccountAccessToken'
payload: { ... }
Extract JsType
Deserialize to ResponseWrapper
Extract payload field
AccessTokenPayload
List
BrandInfo
Token expiration data
Account objects
access/refresh tokens
Concrete Example: AccessTokenPayload
JSON Structure
The following JSON structure represents an access token response:
{
"type": "brokerageAccountAccessToken",
"payload": {
"accountTokens": [{
"account": {
"accountId": "2wwwc105-5xx-4390x",
"accountName": "xx9xxx226",
"fund": 5.36,
"cash": 5.26,
"isReconnected": false,
"frontAccountId": "wow_id"
},
"accessToken": "8/luwjLWf/QxxfilS2r",
"refreshToken": "#34381lmefl93"
}],
"brokerType": "alpaca",
"brokerName": "Alpaca",
"brokerBrandInfo": {
"brokerLogo": "iVBORwxxxxxSUhEUgAAA",
"brokerPrimaryColor": "#FFF",
"logoLightUrl": "http://logoLightUrl",
"logoDarkUrl": "http://logoDarkUrl",
"iconLightUrl": "http://iconLightUrl",
"iconDarkUrl": "http://iconDarkUrl"
},
"expiresInSeconds": 200,
"refreshTokenExpiresInSeconds": 300
}
}
Resulting Kotlin Objects
The JSON deserializes to a hierarchy of Kotlin data classes:
AccessTokenPayload(
accountTokens = listOf(
AccountToken(
account = Account(
accountId = "2wwwc105-5xx-4390x",
accountName = "xx9xxx226",
fund = 5.36,
cash = 5.26,
isReconnected = false,
frontAccountId = "wow_id"
),
accessToken = "8/luwjLWf/QxxfilS2r",
refreshToken = "#34381lmefl93"
)
),
brokerType = "alpaca",
brokerName = "Alpaca",
brokerBrandInfo = BrandInfo(
brokerLogo = "iVBORwxxxxxSUhEUgAAA",
brokerPrimaryColor = "#FFF",
logoLightUrl = "http://logoLightUrl",
logoDarkUrl = "http://logoDarkUrl",
iconLightUrl = "http://iconLightUrl",
iconDarkUrl = "http://iconDarkUrl"
),
expiresInSeconds = 200,
refreshTokenExpiresInSeconds = 300
)
Response Wrapper Pattern
The system uses a wrapper pattern for complex payloads where the actual data is nested within a payload field:
Message Structure Pattern
Actual Payload Classes
Response Wrapper Classes
JSON Message Format
Root JSON Object
type: string
payload: object
AccessTokenResponse
TransferFinishedResponse
DelayedAuthResponse
AccessTokenPayload
TransferFinishedPayload
DelayedAuthPayload
Error Handling
The deserialization system includes error handling for malformed or error-type messages:
- Type Detection Errors - Unknown or null types return
nullfrom the deserialization process - Error Messages - Messages with
type: "error"are deserialized toJsErrorobjects and throwIllegalStateException - Deserialization Failures - JSON parsing errors are handled by the underlying JSON converter implementation
Error Message Processing
JSON with type: 'error'
Deserialize to JsError
Extract errorMessage field
Use default if null
throw IllegalStateException
Special Cases
TrueAuth Link Extraction
For openTrueAuth messages, the system uses a different approach, converting the JSON to a Map and extracting the link field directly:
Type.openTrueAuth -> {
val link = jsonConverter.toMap(json)["link"]
LinkEvent.TrueAuth(link.toString())
}
Simple Event Types
Some message types like close, done, showClose, and loaded don't require deserialization of complex payloads and map directly to sealed LinkEvent objects.
Testing Framework
The system includes comprehensive testing for JSON deserialization:
- Unit Tests - Test individual payload deserialization with mock JSON data
- Integration Tests - Test the complete flow from JSON to
LinkEventobjects - Sample Data - Test resources contain realistic JSON examples for validation
The test framework uses a combination of actual JSON files and programmatically constructed expected objects to validate the deserialization accuracy.