Scala Json隐式读取:类型不匹配?

Scala Json隐式读取:类型不匹配?,scala,playframework,implicit,Scala,Playframework,Implicit,我使用的是Play 2.3.4,我定义了一个简单的模型类: case类用户( @身份证 id:Int, 名称:String )扩展模型 对象用户{ def find()={/*此处有一些代码*/} 隐式对象UserFormat扩展格式[用户]{ def reads(json:JsValue)=用户( (json \“id”)。作为[Int], (json \“name”)。作为[字符串] ) def写入(user:user)=JsObject(Seq(“id”->id,“name”->name)

我使用的是Play 2.3.4,我定义了一个简单的模型类:

case类用户(
@身份证
id:Int,
名称:String
)扩展模型
对象用户{
def find()={/*此处有一些代码*/}
隐式对象UserFormat扩展格式[用户]{
def reads(json:JsValue)=用户(
(json \“id”)。作为[Int],
(json \“name”)。作为[字符串]
)
def写入(user:user)=JsObject(Seq(“id”->id,“name”->name))
}
}
这很简单。但我得到了一个编译错误:

Error:(31, -1) Play 2 Compiler: 
 /Users/asheshambasta/code/finit/app/models/users/User.scala:31: type mismatch;
  found   : models.devices.User
  required: play.api.libs.json.JsResult[models.users.User]

我做错了什么?

上面的代码有几个问题。您收到的编译错误是因为
reads(json:JsValue)
应该返回
JsResult
,而不是模型。这是因为在定义
读取时需要考虑失败
id
name
writes
中还需要是
user.id
user.name
。这将汇编:

object User {

    implicit object UserFormat extends Format[User] {
        def reads(json: JsValue) = JsSuccess(User(
            (json \ "id").as[Int],
            (json \ "name").as[String]
        ))

        def writes(user: User) = Json.obj("id" -> user.id, "name" -> user.name)
    }
}
但是,如果JSON中有错误,这将引发异常,因为
as[T]
不安全

scala> val testJs = Json.parse("""{"id":"2", "name": "test"}""")
testJs: play.api.libs.json.JsValue = {"id":"2","name":"test"}

scala> testJs.validate[User]
play.api.libs.json.JsResultException: JsResultException(errors:List((,List(ValidationError(error.expected.jsnumber,WrappedArray())))))
以这种方式为简单对象定义
读取
几乎总是不值得的,使用JSON组合符可以更好地完成

object User {
    implicit val reads: Reads[User] = (
        (__ \ "id").read[Int] and 
        (__ \ "name").read[String]
    )

    implicit val writes: Writes[User] = (
        (__ \ "id").write[Int] and 
        (__ \ "name").write[String]
    )    
}
JSON组合器不会像第一段代码那样抛出异常,它们会在验证时将所有错误累积到
JsResult
中。在这样一个简单的情况下,JSON inception会更好:

object User {
    implicit val format: Format[User] = Json.format[User]   
}

还有
Json.reads[T]
Json.writes[T]
宏,以防您需要一些自定义的
reads
而不是
writes
或其他方式。

回答得好,非常感谢。它解决了我的问题,也有助于使事情更清楚。