Konverter und offene Properties
Ein Konverter gibt einem Wert seine eigene Textform. Eine offene Property sammelt die JSON-Felder, die die Klasse nicht deklariert.
Konverter
Ein Wert als ein JSON-String
@UseConverter nennt eine Unterklasse von JacksonJsonConverter. toJson macht aus dem Wert einen String, der als JSON-String geschrieben wird; toJava liest diesen String zurück.
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
}
Ausgabe
{"total":"129.90 EUR","@type":"InvoiceDto"}
Der Standard-Konverter ist Jackson
JacksonJsonConverter selbst schreibt den Wert mit Jackson und dem Scala-Modul und liest ihn über den Rohtyp der Property zurück. Leite nur für ein eigenes Format ab.
Offene Properties
Felder, die die Klasse nicht kennt
Eine Map mit @JsonbAnyProperty bekommt jedes JSON-Feld, das keine andere Property verarbeitet. Beim Serialisieren werden ihre Einträge wieder als Felder der obersten Ebene geschrieben.
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}
Ausgabe
user.name // Patrick
user.attributes // {nickname=Pat, score=7}
Die Map muss existieren
Wie jede Collection muss die offene Map initialisiert sein. @type landet nie darin.