如何使用部分数据从json填充案例类?

cod*_*dez 7 scala lift-json

import net.liftweb.json._
import net.liftweb.json.JsonParser._

object test02 extends App {
    implicit val formats = DefaultFormats
    case class User(
        id: Int = 0,
        name: String = "John Doe",
        gender: String = "M")

    val s1=""" {"id":1,"name":"Bill","gender":"M"} """
    var r1=Serialization.read[User](s1)
    println(r1)

    val s2=""" {"id":1} """
    var r2=Serialization.read[User](s2)
    println(r2)  

}
Run Code Online (Sandbox Code Playgroud)

Second Serialization.read导致异常:net.liftweb.json.MappingException:名称没有可用值.

我怎么可能从json读取数据到case类,但是如果缺少某些字段,它们会被case类的默认值替换掉?

Fai*_*aiz 5

看起来很长一段时间都有这样的公开票:https://www.assembla.com/spaces/liftweb/tickets/534

与此同时,一种选择是使用Option:

    case class User(
        id: Int = 0,
        name: Option[String],
        gender: Option[String]) {
      def defaults = copy(
        name   = name   orElse Some("John Doe"),
        gender = gender orElse Some("M"))
    }
    // ...        
    val s2=""" {"id":1} """
    var r2=Serialization.read[User](s2)
    println(r2)  
Run Code Online (Sandbox Code Playgroud)

那应该给你:

 User(1,None,None)
Run Code Online (Sandbox Code Playgroud)

你可以使用这样的东西填写默认值:

 val r2 = Serialization.read[User](s2).defaults

 // r2: User = User(1,Some(John Doe),Some(M))
Run Code Online (Sandbox Code Playgroud)

另一种选择是为您的case类使用其他构造函数:

 case class User(id: Int, name: String, gender: String)
 object User {
   def apply(id:Int): User = User(id, "John Doe", "M")
 }
Run Code Online (Sandbox Code Playgroud)


joh*_*ren 5

如何使用play json库执行此操作,但是,您必须在解析器中提供默认值,而不仅仅是值的默认值:

case class User(id: Int, name: String, gender: String)

import play.api.libs.json._
import play.api.libs.functional.syntax._

implicit val userReads: Reads[User] = (
  (__ \ "id").read[Int] and
  (__ \ "name").read[String].or(Reads.pure("John Doe")) and
  (__ \ "gender").read[String].or(Reads.pure("Male"))
)(User)

Json.fromJson[User](Json.parse("""{"id":1,"name":"Bill","gender":"M"}"""))

Json.fromJson[User](Json.parse("""{"id":1}"""))
Run Code Online (Sandbox Code Playgroud)

我猜你可以通过创建User的模板实例,然后从每个字段传递默认值Reads.pure而不是在那里硬编码字符串来提供默认参数的默认值.