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

Scala Play 2.4.11:无法反序列化以Case Class为键的Map,求原因

解决Play JSON解析Map[自定义Case Class, Long]时的"No implicit format"异常

这个问题的核心原因很直白:Play JSON的默认Map序列化/反序列化只支持键为字符串(或能自动转为字符串的基础类型,比如Int、Long),而你的ItemCategory是自定义的case class,Play不知道怎么把它转换成JSON要求的字符串键,也不知道怎么把JSON的字符串键转回ItemCategory对象,所以就抛出了缺少隐式Format的异常。

解决方案:为自定义键类型实现KeyWrites和KeyReads

Play JSON专门提供了KeyWrites和KeyReads两个类型类,用来处理Map键的序列化(对象转字符串键)和反序列化(字符串键转对象)。你需要为ItemCategory实现这两个类型类,之后Play就能自动处理Map[ItemCategory, Long]了。

步骤1:根据你的JSON结构实现键的转换逻辑

首先得明确你的JSON中,itemCounters的键是什么格式。比如假设你的JSON长这样(键是Repository的env值):

{
  "items": [
    {
      "path": "/api/v1",
      "itemCounters": {
        "prod": 20,
        "dev": 8
      }
    }
  ]
}

那对应的KeyWrites和KeyReads可以这么写:

// 把ItemCategory转换成JSON字符串键:这里直接用repository的env值
implicit val itemCategoryKeyWrites: KeyWrites[ItemCategory] = 
  KeyWrites(category => category.repository.env)

// 把JSON字符串键转回ItemCategory:从字符串生成Repository和ItemCategory
implicit val itemCategoryKeyReads: KeyReads[ItemCategory] = 
  KeyReads { envStr =>
    JsSuccess(ItemCategory(Repository(envStr)))
  }

如果你的JSON键是更复杂的格式(比如"repo-prod"这样的拼接字符串),只需要调整转换逻辑就行:

// 复杂键的示例:序列化时拼接字符串
implicit val itemCategoryKeyWrites: KeyWrites[ItemCategory] = 
  KeyWrites(category => s"repo-${category.repository.env}")

// 反序列化时拆分字符串
implicit val itemCategoryKeyReads: KeyReads[ItemCategory] = 
  KeyReads { keyStr =>
    keyStr.split("-") match {
      case Array("repo", env) => JsSuccess(ItemCategory(Repository(env)))
      case _ => JsError("Invalid key format for ItemCategory")
    }
  }

步骤2:保留原有的Format推导代码

实现完KeyWrites和KeyReads后,原来的自动推导代码就能正常工作了,Play会自动使用这两个类型类处理Map的键:

implicit lazy val repositoryFormat = Json.format[Repository]
implicit lazy val itemCategoryFormat = Json.format[ItemCategory]
implicit lazy val itemFormat = Json.format[Item]
implicit lazy val itemsFormat = Json.format[Items]

Json.parse(str).as[Items]

关键提醒

JSON的语法要求键必须是字符串,所以你的自定义类型作为Map键时,必须能双向映射到字符串——这个映射逻辑要和你的实际JSON结构完全匹配,否则会出现解析失败或者序列化结果不符合预期的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:16:54