2015-05-20 34 views
0

我在斯卡拉的自定义数据类型的简单值:编写自定义对象JSON作为斯卡拉(JSON读取/写入)

case class GPID(value: Int) { 
    // ... other stuff ... 

    implicit val writesGPID = new Writes[GPID] { 
     def writes(g: GPID): JsValue = { 
      Json.obj(
       "GPID" -> g.value 
      ) 
     } 
    } 

    implicit val reads: Reads[GPID] = (
     (__ \ "GPID").read[Int] 
     ).map(GPID(_)) 
} 

正如你所看到的,它有一个读/写的方法,但这种结果在这样的输出:

“ID”:{ “GPID”:1000}

但是,我们只是希望它的序列化/反序列化就像一个普通的诠释:

“ID”:1000

我一直在试图找出如何重写读/写,但我运气不好...任何建议,将不胜感激!

谢谢。

回答

2

我添加了一些验证,修改您的需求。

object GPID { 
    def unapply(in: Int): Option[GPID] = Option(in).filter(_ > 0).map(apply) 

    implicit val reads = new Reads[GPID] { 
    def reads(in: JsValue) = 
     Option(in) 
     .flatMap { 
      case JsNumber(value) => Some(value) 
      case _ => None 
     } 
     .flatMap(num => unapply(num.toInt)) 
     .map(JsSuccess(_, __)) 
     .getOrElse(JsError(__, "validate.error.expected.GPID")) 
    } 

    implicit val writes = new Writes[GPID] { 
    def writes(g: GPID) = JsNumber(g.value) 
    } 

} 
+0

嗯。更接近,但不完全。它的序列化为'“id”:{“id”:1000}'所以它仍然把它当作一个对象,而不是一个简单的值......另外,我不能使用隐式读取,因为:'ScalaReflectionException:value apply封装了多个重载替代品,不能被视为一种方法。考虑调用<违规符号> .asTerm.alternatives并手动选择所需的方法。 – Zac

+0

已编辑,立即尝试。 –

+0

所以你需要提供一个!再次编辑。 –