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
相关产品推荐
相关产品推荐

