在另一个自定义格式器中使用自定义Formatter

时间:2014-04-03 08:42:33

标签: json scala

我实现了我的自定义读/写格式化程序,以便将类序列化为json。

这个问题仍然存在问题:Define different formatters for same class in the same trait

我想做什么,我有Tenant类的Product类列表,租户的格式化程序不是隐式的,它是自定义格式化程序。

val hsmTenantFormat = new Format[Tenant]
{
def writes(tenant: Tenant): JsValue = 
{
  val items = tenant.items.getOrElse(List[Product]())

  Json.obj(
    "items" -> tenant.items, //==> This line throw compile error since Product is not with implicit - cannot find formatter
    "prefixAndroid" -> tenant.prefixAndroid,
    "prefixIOS" -> tenant.prefixIOS,
    "er" -> tenant.er,
    "erMessage" -> tenant.erMessage
    )
}

def reads(json: JsValue): JsResult[Tenant] = 
{
  val items = (json \ "items").as[Option[List[Product]]]
  var itemsReal:Option[List[Product]] = None
  if (items.isDefined)
  {
      itemsReal = Some(items.get)
  }  
JsSuccess(new Tenant(
  itemsReal,
  (json \ "prefixAndroid").as[String],
  (json \ "prefixIOS").as[String],
  (json \ "er").as[Int], 
  (json \ "erMessage").as[String]
))
}
}}    

当Product隐含时,这是有效的,但是当我希望使用customProductFormatter - 一个没有隐式的,我无法找到设置位置时会发生什么。

谢谢!

这是我的产品格式化程序:

implicit val hsmProductFormat = new Format[Product] 
{
  def writes(item: Product): JsValue = 
  {
    val retailers = item.r.getOrElse(List[Retailer]())
    val images = item.images.getOrElse(List[String]())
    Json.obj(
      "u" -> item.u,
      "s" -> item.s,
      "z" -> item.z,
      "n" -> item.n,
      "v" -> item.v,
      "vu" -> item.vu,
      "t" -> item.t,
      "r" -> retailers,
      "images" -> images
    )
  }

  def reads(json: JsValue): JsResult[Product] = 
  {
    val retailers = (json \ "r").as[Option[List[Retailer]]]
    var retaliersReal:Option[List[Retailer]] = None
    if (retailers.isDefined)
    {
      retaliersReal = Some(retailers.get)
    }

    val images = (json \ "images").as[Option[List[String]]]
    var imagesReal:Option[List[String]] = None
    if (images.isDefined)
    {
      imagesReal = Some(images.get)
    }      
  JsSuccess(new Product(
    (json \ "u").as[String],
    (json \ "s").as[Int],
    (json \ "z").as[Int],
    (json \ "n").as[String],
    (json \ "v").as[String],
    (json \ "vu").as[String],
    (json \ "t").as[String],
    retailers,
    imagesReal
  ))
  }
}

我希望从产品格式声明中删除隐含,但如果我这样做,则编译找不到Product的格式化程序!

1 个答案:

答案 0 :(得分:3)

好的,我希望我能理解你的问题。我认为有两种方法可以解决这个问题。

首先,在您的租户格式中声明Product的隐式格式,以便它可以“赶上”":

def writes(tenant: Tenant): JsValue = 
{
  val items = tenant.items.getOrElse(List[Product]())

  implicit val productWriter = Product.hsmProductFormat // <--- this should work

  Json.obj(
    "items" -> tenant.items, 
    "prefixAndroid" -> tenant.prefixAndroid,
    "prefixIOS" -> tenant.prefixIOS,
    "er" -> tenant.er,
    "erMessage" -> tenant.erMessage
    )
}

第二种方法是直接引用所需的写入:

def writes(tenant: Tenant): JsValue = 
{
  val items = tenant.items.getOrElse(List[Product]())

  Json.obj(
    "items" -> Product.hsmProductFormat.writes(tenant.items: _*), //as you have a List[Product] here, just add a ": _*" thing when calling writes
    "prefixAndroid" -> tenant.prefixAndroid,
    "prefixIOS" -> tenant.prefixIOS,
    "er" -> tenant.er,
    "erMessage" -> tenant.erMessage
    )
}

干杯