Java scala jackson处理任何类型,可能需要自定义拦截器

Java scala jackson处理任何类型,可能需要自定义拦截器,java,json,mongodb,scala,Java,Json,Mongodb,Scala,我目前正在重写我们的一个应用程序,它使用PostgreSQL,现在应该使用Mongo 架构非常简单 db => case class => rest api 我们正在使用scala jackson,一切正常,除了一些小麻烦,我只是在寻找正确的方法 考虑一下这个案例类来理解我的烦恼 case class Test(val id:String, val value:Any) 应用程序中的值可以是数字或字符串,数字可以是整数或双精度 因此,当我们从遗留应用程序接收到这样的JSON时:

我目前正在重写我们的一个应用程序,它使用PostgreSQL,现在应该使用Mongo

架构非常简单

db => case class => rest api
我们正在使用scala jackson,一切正常,除了一些小麻烦,我只是在寻找正确的方法

考虑一下这个案例类来理解我的烦恼

case class Test(val id:String, val value:Any)
应用程序中的值可以是数字或字符串,数字可以是整数或双精度

因此,当我们从遗留应用程序接收到这样的JSON时:

{ id:"a",value:"test"}
它被正确地映射,并产生预期的字符串类型String

但假设:

{ id:"b", value:"1"}
我们希望将其映射为字符串Integer。但显然杰克逊认为这是一个字符串,并将其映射到字符串,字符串

有什么透明的方法可以做到这一点吗?我的想法是,像杰克逊的拦截器一样的东西会很好,这是一个简单的测试

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
在这个例子中

显然,我可以事先编写一个通用解析器并将数据格式转换为正确的格式,但我更希望这样做是透明的,因为我们永远不知道用户何时会提交遗留的JSON格式,并带有此错误,因此可能会损坏系统


thx

好的,看起来这比exspected容易,只需编写一个客户序列化程序并注释我们需要它的一个字段

解决方案

实例:

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
                     )

“1”是一个字符串,由于MongoDB支持,如果它以这种方式检索文档,则在插入数据时会出现问题,而不仅仅是在读取时。正确,这是我们的传统格式,在mongo之前。因此,当用户提交旧格式时,我们会自动转换它