【问题标题】:How to handle optional fields in JSON parsing in play 2.1如何在play 2.1中处理JSON解析中的可选字段
【发布时间】:2012-12-21 21:21:52
【问题描述】:

我正在使用新的 Play 2.1-RC1 框架,并且我有一个具有 Option[] 字段的类,如下所示:

import play.api.libs.json._
import play.api.libs.json.util._
import play.api.libs.json.Reads._
import play.api.libs.json.Writes._
import play.api.libs.json.Format._
import play.api.libs.functional.syntax._

case class Test(name: String, value: Option[String])

object Test {
  implicit val testFormat = (
    (__ \ "name").format[String] and
    (__ \ "value").format[Option[String]] 
  )(Test.apply, unlift(Test.unapply))
  def fromJson(js: String): Test = {
    Json.fromJson[Test](Json.parse(js)).fold(
        valid   = { t => t},
        invalid = { e => {
          val missingField = (e(0)._1).toString.substring(1)
          val badJs = js.trim
          val newJs = badJs.substring(0, badJs.length()-1)+",\""+missingField+"\":null}"
          fromJson(newJs)
        }} 
    )
  }
}

我希望能够处理省略了可选“值”数据的 JSON 字符串,例如

val y = """{"name":"someone"}"""

(已编辑问题) 如验证步骤所示,我可以重写 json 字符串(相当笨拙),但是 有没有更简单的模式可以用来为缺少的可选字段提供无?请注意,这种重写不适用于嵌套结构,或者我不能简单地附加缺失字段的任何地方。

【问题讨论】:

    标签: scala playframework playframework-2.0


    【解决方案1】:

    你可以这样做:

    import play.api.libs.json._
    import play.api.libs.functional.syntax._
    
    case class Test(name: String, value: Option[String])
    
    implicit val testFormat = Json.format[Test]
    
    def hoge = Action(Json.parse.json) { request => 
        Json.fromJson[Test](request.body)
        ...
    }
    

    【讨论】:

    • 唯一的问题是json不是来自请求,而是来自websocket。
    • @NickStoughton Iteratee.foreach[JsValue](event => Json.fromJson[Test](event))
    • 谢谢!这有帮助!但是,如果传入的 JSON 缺少格式化程序(读取器)期望的字段,仍然存在问题。我更新了上面的示例以显示一种解决方法。
    【解决方案2】:

    好的……所以答案很简单。使用

    fomatOpt()
    

    用于可选字段。所以测试格式化程序现在看起来像这样:

    import play.api.libs.json._
    import play.api.libs.json.util._
    import play.api.libs.json.Reads._
    import play.api.libs.json.Writes._
    import play.api.libs.json.Format._
    import play.api.libs.functional.syntax._
    
    case class Test(name: String, value: Option[String])
    
    object Test {
      implicit val testFormat = (
        (__ \ "name").format[String] and
        (__ \ "value").formatOpt[String] 
      )(Test.apply, unlift(Test.unapply))
    
      def fromJson(js: String): Test = {
        Json.fromJson[Test](Json.parse(js)).fold(
          valid   = { t => t},
          invalid = { e => {
            println("BAD JSON!")
            null
          }} 
        )
      }
    }
    

    【讨论】:

    • 使用 scala 宏注入 Reads/Writes/Format 的情况如何?例如,在您的情况下,我们可以只写 implicit val testFormat = Json.format[Test] 在这种情况下您如何管理可选的 JSON 值?
    猜你喜欢
    • 1970-01-01
    • 2015-12-04
    • 1970-01-01
    • 1970-01-01
    • 2018-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-03
    相关资源
    最近更新 更多