Я хочу использовать json4s для преобразования класса дела в Map[String, Any]
.Я знаю, как использовать для этого отражение в scala, но я не хочу иметь дело со сложностью в моем коде.
С помощью json4s можно легко преобразовать класс case в JsonAST.JValue
.С JsonAST.JValue
можно извлечь Map[String,Any]
.
Однако Map[String,Any]
не соответствует ожидаемому.
import org.json4s.native.JsonMethods._
import org.json4s._
import java.util.Currency
case class A(currency: Currency, i: Int, b: Boolean)
case object CurrencySerializer
extends CustomSerializer[Currency](
_ =>
({
case JString(s) => Currency.getInstance(s)
case JNull => null
}, {
case currency: Currency => JString(currency.getCurrencyCode)
})
)
implicit val formats = DefaultFormats + CurrencySerializer
val currency = Currency.getInstance("USD")
val a = A(currency, 1, true)
val json = Extraction.decompose(a)
val m = json.extract[Map[String,Any]]
В m: Map[String, Any]
,
scala> m("i").asInstanceOf[BigInt]
res16: BigInt = 1
scala> m("b").asInstanceOf[Boolean]
res18: Boolean = true
scala> m("currency").asInstanceOf[Currency]
java.lang.ClassCastException: java.lang.String cannot be cast to java.util.Currency
... 38 elided
scala> m("currency").asInstanceOf[String]
res23: String = USD
m("currency")
на самом деле String
, однако я ожидаю, что это будет java.util.Currency
.
Я думаю, я знаю причину.Промежуточное значение json
равно JObject(List((currency,JString(USD)), (i,JInt(1)), (b,JBool(true))))
, т. Е. Валюта представлена как JString("USD")
в JsonAST.JValue
.Затем код выполняется для возврата String
.
Правильно ли выполнен мой анализ?Что я могу сделать, чтобы вместо m("currency")
получить java.util.Currency
?(все еще используя json4s)