Json#arr w / List [Int]输入

时间:2016-11-03 17:33:57

标签: json scala playframework-2.0

在播放JSON answer中对List[A]进行编码时,请看这个有用的library

我尝试使用Json#arr

import play.api.libs.json._

scala> Json.arr( 1, 2, 3 )
res21: play.api.libs.json.JsArray = [1,2,3]

到目前为止一切运作良好,但如果我有一个List[Int]

怎么办?
scala> Json.arr( List(1,2,3) )
res22: play.api.libs.json.JsArray = [[1,2,3]] // not what I wanted

我试图将List[Int]作为var-args传递(如果这是正确的术语):

scala> Json.arr( List(1,2,3): _* )
<console>:18: error: type mismatch;
 found   : List[Int]
 required: Seq[play.api.libs.json.Json.JsValueWrapper]
       Json.arr( List(1,2,3): _* )
                     ^

但那没用。

然后,我尝试创建List[JsValueWrapper],然后通过var-args将其传递给Json#arr

scala>  List(1,2,3).map(Json.toJsFieldJsValueWrapper)
<console>:18: error: No Json serializer found for type T. Try to implement an implicit Writes or Format for this type.
        List(1,2,3).map(Json.toJsFieldJsValueWrapper)
                             ^

虽然失败了,但以下内容适用于单个Int

scala> Json.toJsFieldJsValueWrapper(1)
res27: play.api.libs.json.Json.JsValueWrapper = JsValueWrapperImpl(1)

scala> Json.arr(res27)
res28: play.api.libs.json.JsArray = [1]

如何将List[Int]传递到Json.arr以获得[1,2,3]的输出,即由JsArray组成的JsNumber

2 个答案:

答案 0 :(得分:3)

您可以使用Json.toJson,验证为JsArray,如果无效,则返回空的:

scala> val list = List(1, 2, 3)
list: List[Int] = List(1, 2, 3)

scala> Json.toJson(list).validate[JsArray].getOrElse(JsArray())
res6: play.api.libs.json.JsArray = [1,2,3]

您还可以使用Json.arr稍微修改您的lambda:

scala> Json.arr(list.map(Json.toJsFieldJsValueWrapper(_)): _*)
res10: play.api.libs.json.JsArray = [1,2,3]

似乎没有括号,编译器无法推断出T是什么。这是因为编译器尝试在eta扩展匿名函数之前解析隐式,因此它不知道将向Json.toJsFieldJsValueWrapper传递什么参数。 Json.toJsFieldJsValueWrapper(_)根本不同,因为它扩展到略有不同的Function1

 x => Json.toJsFieldJsValueWrapper(x)

编译器知道x将是Int,因此隐式Writes[Int]已解析。

答案 1 :(得分:0)

如何使用Json.toJson并投射到JsArray(如果需要)?

scala> Json.toJson(List(1,2,3)).as[JsArray]
res0: play.api.libs.json.JsArray = [1,2,3]