AnnKont
AnnKont

Reputation: 506

Jackson JSON Serialization without field name from one string row

I have this JSON to deserialize:

"data": {
  "type": 18,        
  "msg": "firstName,lastName,15" 
  "timestamp": 1551770400000 
}

I want to get this data in my model:

class DataDto(
    type: String,
    timestamp: Long,
    msg: DataMsgDto?
) {
    @JsonFormat(shape = JsonFormat.Shape.STRING)
    @JsonPropertyOrder("firstName", "lastName", "age")
    class DataMsgDto(
        firstName: String,
        lastName: String,
        age: Long
    )
}

I use this code to get data:

DataBuffer payload //this is what I get from server
val jsonNode = objectMapper.readTree(payload.toString(StandardCharsets.UTF_8))
objectMapper.treeToValue(jsonNode, DataDto::class.java)

But this does not work because in msg I don't have fields. So, how can I do this?

Upvotes: 1

Views: 193

Answers (1)

aSemy
aSemy

Reputation: 7129

You have a JSON property that contains comma-separated values. The JSON message is valid, and can be deserialized by Jackson.

It's possible to write custom Jackson code that can handle this case automatically

But the most practical way to solve this is unlikely to be digging around trying to make Jackson understand msg, or writing a custom deserializer. Instead, allow msg to be a String

class DataDto(
    val type: String,
    val timestamp: Long,
    // just use a normal String for msg
    val msg: String?
) 

And then manually decode it in Kotlin

fun parseDataDtoMsg(dto: DataDto): DataMsgDto? {
  val msgElements = dto.msg?.split(",") ?: return null

  // parse each message - you can chose whether to 
  // throw an exception if the `msg` does not match what you expect, 
  // or ignore invalid data and return `null`

  val firstName = ...
  val lastName = ...
  val age = ...

  return DataDtoMsg(
      firstName = firstName,
      lastName = lastName,
      age = age,
  )
}

data class DataMsgDto(
    val firstName: String
    val lastName: String
    val age: Long,
)

Upvotes: 2

Related Questions