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

如何使用Play JSON OFormat宏解析含Option的List类型?

Solution for Parsing List[Option[Person]] with Play JSON OFormat Macros

The issue here is that while Play JSON provides implicit deserializers for Option[A] (when a Reads[A] exists) and List[A], sometimes the compiler needs a little help resolving the combined Reads[List[Option[Person]]] implicitly. Here's how to fix it without your temporary manual mapping:

Step-by-Step Fix

  1. Ensure you have all necessary implicit imports: Play JSON's core deserialization helpers are in Reads._, so add that import to bring in the implicit Reads for Option and List combinations.
  2. Use the existing OFormat for Person: Your existing personFormat already provides both Reads and Writes for Person, which is all we need to build the deserializer for List[Option[Person]].

Here's the corrected code:

import play.api.libs.json._
import play.api.libs.json.Reads._ // Critical for combining Option and List reads

val text = """[{"name": "John", "age": 30}, null, {"name": "Steve", "age": 34}]"""

case class Person(name: String, age: Int)
implicit val personFormat: OFormat[Person] = Json.format[Person]

// Now validate will work as expected
val data = Json.parse(text).validate[List[Option[Person]]]

// To get the result (handle success/failure properly in production code!)
data match {
  case JsSuccess(people, _) => println(people) // List(Some(Person(John,30)), None, Some(Person(Steve,34)))
  case JsError(errors) => println(s"Parsing errors: $errors")
}

Why This Works

  • Play JSON automatically derives a Reads[Option[Person]] from your Reads[Person] (provided by personFormat). This deserializer maps JSON null to None and valid Person JSON objects to Some(Person(..)).
  • The Reads.list implicit takes that Reads[Option[Person]] and builds a Reads[List[Option[Person]]] to handle the JSON array.
  • By importing Reads._, we make sure these implicit combiners are visible to the compiler when it tries to resolve Reads[List[Option[Person]]] for the validate call.

Avoiding Common Pitfalls

Don't forget to handle the JsResult properly (like the pattern match above) instead of using .get (which will throw exceptions on parsing errors) — your temporary solution uses .get, which is risky for production code. The validate method gives you a safe way to handle success and failure cases.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 03:46:38