简体   繁体   English

使用Play的(2.2)Scala JSON组合器编写在案例类中找不到的任意值

[英]Write an Arbitrary Value Not Found in a Case Class Using Play's (2.2) Scala JSON Combinators

I'd like to implement a Writes that emits a JSON object that's not found in the class being serialized. 我想实现一个Writes ,它发出在序列化的类中找不到的JSON对象。

For case class: 对于案例类:

case class Foo(i:Int, s:String)

I'm looking to produce: 我正在寻找生产:

{
  "i": <int>,
  "s": "<string>",
  "other": "Some value."
}

The naïve first attempt was: 天真的第一尝试是:

val writes: Writes[Foo] = ((
  (__ \ "i").write[Int] and
    (__ \ "s").write[String] and
    (__ \ "other").write("Some value.")
  )(unlift(Foo.unapply))

Naturally, that won't compile as the subsequent and calls produce a CanBuild3 and Foo 's unapply produces a Tuple2 . 自然地,将不编译作为随后的and呼叫产生CanBuild3Foounapply产生Tuple2 I'd looked into appending a value to the result, producing a Tuple3 , but what I've found looks pretty bad and the language maintainers will not implement it . 我曾考虑将一个值添加到结果中,以生成一个Tuple3 ,但是我发现的结果看起来很糟糕语言维护者不会实现它

There are ways to work-around this, but I'd rather not pollute my model classes with these decorator values I'd like added to the resulting JSON. 有多种方法可以解决此问题,但我不希望使用我想添加到结果JSON中的装饰值来污染我的模型类。

Any suggestions? 有什么建议么?

It's worth noting you can go the other direction, providing values with Reads.pure for cases where a value does not exist in JSON but is specified by the resulting object. 值得注意的是,您可以朝另一个方向发展,在JSON中不存在但由结果对象指定的值的情况下,为Reads.pure提供值。

You can do this pretty straightforwardly by desugaring a bit: 您可以通过略微调整一下位置来直接完成此操作:

val writes: Writes[Foo] = (
  (__ \ "i").write[Int] and
  (__ \ "s").write[String] and
  (__ \ "other").write[String]
)(foo => (foo.i, foo.s, "Some value."))

The unlift(Foo.unapply) is just a fancy way to get a function from a Foo to a tuple of the kind required by the preceding applicative builder expression, and you can replace it with your own function that can add whatever you want. unlift(Foo.unapply)只是一种将Foo的函数转换为前面的应用生成器表达式所需的元组的unlift(Foo.unapply)方法,您可以将其替换为自己的函数,该函数可以添加所需的任何内容。

If you really wanted even cleaner syntax, you could use Shapeless : 如果您真的想要更简洁的语法,可以使用Shapeless

import shapeless.syntax.std.tuple._

val writes: Writes[Foo] = (
  (__ \ "i").write[Int] and
  (__ \ "s").write[String] and
  (__ \ "other").write[String]
)(_ :+ "Some value.")

It's beautiful, but may be overkill. 它很漂亮,但可能会过大。

Another option is to use an object builder that implements an unapply that returns the extra values. 另一种选择是使用实现的目标建设者unapply返回多余的值。 This makes the Writes cleaner, but adds a new object. 这样可以使Writes更加整洁,但可以添加一个新对象。 I have found this useful though as both the apply and unapply method can be used for extra massaging of data into the final object (eg: https://stackoverflow.com/a/22504468/1085606 ) 我发现这很有用,尽管apply和unapply方法都可以用于将数据额外按摩到最终对象中(例如: https : //stackoverflow.com/a/22504468/1085606

Example: 例:

case class Foo(i: Int, s: String)

object FooBuilder {
  def unapply(foo: Foo): Option[(Int, String, String)] = {
    Some((foo.i, foo.s, "Some extra value"))
  }
}

val writes: Writes[Foo] = ((
  (__ \ "i").write[Int] and
    (__ \ "s").write[String] and
    (__ \ "other").write[String]
  )(unlift(FooBuilder.unapply))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用Scala组合器读取case类中的可选json值 - How to read optional json values in case class using scala combinators Scala播放JSON组合器以验证相等性 - Scala play json combinators for validating equality 使用Scala / Play将JSON转换为带有嵌套对象的case类 - Convert JSON to case class with a nested objects using Scala/Play 使用组合器播放2.2 JSON读取:如何处理嵌套的可选对象? - Play 2.2 JSON Reads with combinators: how to deal with nested optional objects? 如何编写Scala Play框架自定义类的多个JSON序列化器反序列化器? - How to write Scala Play framework custom class's multiple JSON serializer deserializer? 在Play2.2 Scala中将通用案例类自动序列化/反序列化为JSON - Automatic serialization/deserialization of generic case classes to/from JSON in Play2.2 Scala 自定义Json使用组合器写入 - 不需要案例类的所有字段 - Custom Json Writes with combinators - not all the fields of the case class are needed Scala Play:如何将 JSON 数组结构映射到 Case Class - Scala Play: How to map JSON array structure to Case Class scala 播放 读取 json 有条件地填充案例 class - scala play Read json conditionally populate case class Play Framework 2.2:没有找到Json解串器 - Play Framework 2.2: No Json deserializer found
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM