【问题标题】:use custom Formatter inside another custom formatter在另一个自定义格式化程序中使用自定义格式化程序
【发布时间】:2014-04-03 08:42:33
【问题描述】:

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

这个问题是继续问题:Define different formatters for same class in the same trait

我想做的是,我在租户类中有一个产品类列表,租户的格式化程序不是隐式的,它是一个自定义格式化程序。

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 的格式化程序!

【问题讨论】:

    标签: json scala


    【解决方案1】:

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

    第一个,在您的租户格式中为 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
        )
    }
    

    干杯

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-03
      • 2018-02-15
      • 2016-11-30
      • 1970-01-01
      • 2012-06-17
      • 2014-02-15
      相关资源
      最近更新 更多