我目前正在重写我们的一个应用程序,它使用PostgreSQL,现在应该使用Mongo。
架构非常简单
db => case class => rest api
我们正在使用scala jackson,一切正常,除了一些小麻烦,我只是在寻找合适的方法。
考虑这个案例类来理解我的烦恼
case class Test(val id:String, val value:Any)
此时我们的应用程序中的值可以是数字或字符串,可以是整数或双数。
所以当我们从我们的遗留应用程序中收到这样的JSON时:
{ id:"a",value:"test"}
它被正确映射并产生预期类型的String,String。
但假设如下:
{ id:"b", value:"1"}
我们希望将此映射为String,Integer。但很明显杰克逊认为它是一个String并将其映射到String,String。
这有什么透明方式吗?我的想法,就像杰克逊的拦截器会很好,这个简单的测试
if type.isDouble == true return double value
else if type.isInteger == true return integer value
else return string value
所以我们最终会以
结束String,Double
String,Integer
String,String
在这个例子中。
显然我可以编写一个通用的解析器并事先将dataformat带到正确的表单中,但我宁愿这样做透明,因为我们永远不知道用户何时会提交遗留的JSON格式,有这个bug,所以可能会破坏系统
THX
答案 0 :(得分:0)
好吧,看起来这比预期更容易,编写客户序列化程序并注释我们需要它的一个字段
找到解决方案here
实际例子:
class NumberDeserializer extends JsonDeserializer[Any] {
override def deserialize(jsonParser: JsonParser, deserializationContext: DeserializationContext): Any = {
val jsonNode: JsonNode = jsonParser.getCodec.readTree(jsonParser)
val content = jsonNode.textValue
try {
content.toInt
} catch {
case e: NumberFormatException => try {
content.toDouble
}
catch {
case e2: NumberFormatException => content
}
}
}
}
用法:
case class Test(
@JsonDeserialize(using = classOf[NumberDeserializer])
value: Any
)