You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Scala中如何解析含泛型类参数的JSON?泛型Getter trait解析

我来帮你解决这个泛型Getter的JSON解析问题!结合json4s的自定义序列化器,我们完全可以通过JSON里的function和type字段来动态匹配对应的实现类和泛型类型,下面是一步步的具体实现方案:

第一步:定义泛型Getter trait和实现类

首先我们先把基础的trait和两个实现类定义好,明确function标识对应类,泛型T对应业务数据类型:

import org.json4s._

// 泛型Getter trait
trait Getter[T] {
  def function: String
  def getValue: T
}

// 字符串类型的Getter实现
class StringGetter(val getValue: String) extends Getter[String] {
  override val function: String = "string_getter"
}

// 整数类型的Getter实现
class IntGetter(val getValue: Int) extends Getter[Int] {
  override val function: String = "int_getter"
}
第二步:实现自定义JsonSerializer

核心逻辑就在这里——我们要在反序列化时,先读取JSON里的function和type字段,分别用来确定实例化哪个实现类、解析泛型类型,然后完成对象的构建:

class GetterSerializer extends CustomSerializer[Getter[_]](format => (
  // 反序列化逻辑(重点)
  {
    case JObject(fields) =>
      // 从JSON字段中提取function和type标识
      val JString(func) = fields.find(_._1 == "function").get._2
      val JString(typeName) = fields.find(_._1 == "type").get._2
      
      // 根据type字段获取对应的泛型Manifest,让json4s知道要解析成什么类型
      val valueManifest: Manifest[_] = typeName match {
        case "String" => manifest[String]
        case "Int" => manifest[Int]
        // 后续可以在这里扩展更多支持的泛型类型
        case _ => throw new IllegalArgumentException(s"不支持的泛型类型: $typeName")
      }
      
      // 提取value字段并根据泛型类型解析
      val JValue(rawValue) = fields.find(_._1 == "value").get._2
      val parsedValue = Extraction.extract(rawValue)(format, valueManifest)
      
      // 根据function字段实例化对应的Getter实现类
      func match {
        case "string_getter" => new StringGetter(parsedValue.asInstanceOf[String])
        case "int_getter" => new IntGetter(parsedValue.asInstanceOf[Int])
        // 后续扩展新的实现类时,在这里添加匹配分支
        case _ => throw new IllegalArgumentException(s"不支持的Getter类型: $func")
      }
    case _ => throw new MappingException("无法反序列化为Getter类型")
  },
  // 序列化逻辑(可选,如果需要把Getter对象转回JSON的话)
  {
    case getter: Getter[_] =>
      val typeName = getter.getValue.getClass.getSimpleName match {
        case "String" => "String"
        case "Integer" => "Int"
        case _ => throw new IllegalArgumentException(s"不支持序列化的类型: ${getter.getValue.getClass}")
      }
      JObject(
        "function" -> JString(getter.function),
        "type" -> JString(typeName),
        "value" -> Extraction.decompose(getter.getValue)(format)
      )
  }
))
第三步:使用自定义序列化器解析JSON列表

现在我们可以用这个序列化器来解析JSON数组,得到List[Getter[_]]:

import org.json4s.jackson.JsonMethods._

object GetterParserDemo extends App {
  // 注册自定义序列化器到json4s的Formats中
  implicit val formats: Formats = DefaultFormats + new GetterSerializer
  
  // 测试用的JSON数组
  val testJson = """
    [
      {"function": "string_getter", "type": "String", "value": "Hello JSON4s"},
      {"function": "int_getter", "type": "Int", "value": 12345}
    ]
  """
  
  // 解析为Getter列表
  val getterList = parse(testJson).extract[List[Getter[_]]]
  
  // 验证解析结果
  getterList.foreach {
    case sg: StringGetter => println(s"StringGetter: ${sg.getValue}")
    case ig: IntGetter => println(s"IntGetter: ${ig.getValue}")
  }
}

关键逻辑说明

  • 反序列化时,type字段的核心作用是提供泛型类型的Manifest,让json4s能正确把value字段解析成对应的数据类型
  • function字段直接映射到具体的实现类,确保我们实例化的是正确的Getter子类
  • 如果后续要扩展新的Getter实现或泛型类型,只需要在序列化器的匹配分支里添加对应的逻辑即可

内容的提问来源于stack exchange,提问作者asantas93

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 07:46:39