Converters and open properties
A converter gives a value its own text form. An open property collects the JSON fields the class does not declare.
Converter
A value as one JSON string
@UseConverter names a subclass of JacksonJsonConverter. toJson turns the value into a string, which is written as a JSON string; toJava reads that string back.
scala
import com.anjunar.json.mapper.annotations.UseConverter
import com.anjunar.json.mapper.converter.JacksonJsonConverter
import com.anjunar.scala.universe.ResolvedClass
case class Money(amount: BigDecimal, currency: String)
class MoneyConverter extends JacksonJsonConverter {
override def toJson(input: Any, resolvedClass: ResolvedClass): String =
val money = input.asInstanceOf[Money]
s"${money.amount} ${money.currency}"
override def toJava(json: String, resolvedClass: ResolvedClass): Any =
val Array(amount, currency) = json.split(" ")
Money(BigDecimal(amount), currency)
}
class InvoiceDto extends DTO {
@(UseConverter @field)(classOf[MoneyConverter])
@(JsonbProperty @field) var total: Money = null
}
Output
{"total":"129.90 EUR","@type":"InvoiceDto"}
The default converter is Jackson
JacksonJsonConverter itself writes the value with Jackson and the Scala module, and reads it back by the property's raw type. Subclass it only for your own format.
Open properties
Fields the class does not know
A map annotated with @JsonbAnyProperty receives every JSON field that no other property handles. On serialization its entries are written as top-level fields again.
scala
import com.anjunar.json.mapper.annotations.JsonbAnyProperty
class UserDto extends DTO {
@(JsonbProperty @field) var name: String = null
@(JsonbAnyProperty @field)
@(JsonbProperty @field)
var attributes: java.util.Map[String, Any] = new java.util.LinkedHashMap[String, Any]()
}
json
{"name": "Patrick", "nickname": "Pat", "score": 7}
Output
user.name // Patrick
user.attributes // {nickname=Pat, score=7}
The map must exist
Like any collection, the open map must be initialized. @type is never collected into it.