PlayFramework 对象 json

PlayFramework obj to json

发件人:https://www.playframework.com/documentation/2.3.x/ScalaJsonHttp

Playframework Scala 方式:

    case class Location(lat: Double, long: Double)

    case class Place(name: String, location: Location)

    object Place {

      var list: List[Place] = {
        List(
          Place(
            "Sandleford",
            Location(51.377797, -1.318965)
          ),
          Place(
            "Watership Down",
            Location(51.235685, -1.309197)
          )
        )
      }

    }

    implicit val locationWrites: Writes[Location] = (
      (JsPath \ "lat").write[Double] and
      (JsPath \ "long").write[Double]
    )(unlift(Location.unapply))

    implicit val placeWrites: Writes[Place] = (
      (JsPath \ "name").write[String] and
      (JsPath \ "location").write[Location]
    )(unlift(Place.unapply))
    Next we write our Action:

    def listPlaces = Action {
      val json = Json.toJson(Place.list)
      Ok(json)
    }

有没有更简单的方法呢?没有所有这些明显的暗示?我只希望它按原样转换所有对象结构。就像在 JS 上使用 JSON.

假设我 O.K。具有默认字段名称和默认对象结构。我可以使用 "default advantage-sugar" 吗?

更新:

NodeJS一样简单,例如:

var list = {"places":[
    {"name":"Sandleford", "location":{"lat": "1", "long": "222"}}, 
    {"name":"Watership Down", "location":{"lat": "2", "long": "333"}},
]}

router.get('/', function(req, res) {
    res.json(list);   
});

毫无疑问应该本地化什么以及如何本地化。

或者像 java 中那样(纯 jackson):

List list = Arrays.asList(place1, place2);
ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter();
String json = ow.writeValueAsString(list);

其中 class 没有注释定义的地方(但有 getter 和 setter,但我不喜欢)。

我可以在 scala 中使用 jackson,但我想知道 'official defaults'.. 在 playframewok 中,scala 可以使用更少的代码(就像它应该的那样)是)。

Json.writes[T]

如果你想要的只是文字序列化到 Json,并且你不想自己编写 Writes 实例,你可以使用 Json.writes[T] 宏来生成 Writes[T] 给你。

import play.api.libs.json._

case class Location(lat: Double, long: Double)

case class Place(name: String, location: Location)

object Place {

  val list: List[Place] = {
    List(
      Place(
        "Sandleford",
        Location(51.377797, -1.318965)
      ),
      Place(
        "Watership Down",
        Location(51.235685, -1.309197)
      )
    )
  }

}

object JsonStuff {
  implicit val locationWrites: Writes[Location] = Json.writes[Location]

  implicit val placeWrites: Writes[Place] = Json.writes[Place]
}

然后在repl上,

scala> import JsonStuff._
import JsonStuff._

scala> import play.api.libs.json._
import play.api.libs.json._

scala> Json.toJson(Place.list)
res0: play.api.libs.json.JsValue = [{"name":"Sandleford","location":{"lat":51.377797,"long":-1.318965}},{"name":"Watership Down","location":{"lat":51.235685,"long":-1.309197}}]

Json 文字

如果您真的想要,您当然可以直接创建和操作JsValue。例如

object Place {
  val JsList =
    JsArray(
      Seq(
        Json.obj(
          ("name" -> "Sandleford"),
          ("location" ->
            Json.obj(
              ("lat" -> 51.377797),
              ("long" -> -1.318965)))),
        Json.obj(
          ("name" -> "Watership Down"),
          ("location" ->
            Json.obj(
              ("lat" -> 51.235685),
              ("long" -> -1.309197))))))

}

关于回复,

scala> Place.JsList
res0: play.api.libs.json.JsArray = [{"name":"Sandleford","location":{"lat":51.377797,"long":-1.318965}},{"name":"Watership Down","location":{"lat":51.235685,"long":-1.309197}}]

尽管这种方法对于除了最琐碎的应用程序之外的所有应用程序都很难使用,我会 强烈建议 反对它。

As isomarcte 已经回答了。我必须这样做(作为无噪音解决方案,这几乎让我满意):

case class Location(lat: Double, long: Double)
case class Place(name: String, location: Location)

// little noise (just too lines, but that could be even one @Json. Could..     
object JsonStuff {
 implicit val locationWrites: Writes[Location] = Json.writes[Location]
 implicit val placeWrites: Writes[Place] = Json.writes[Place]
}

object Application extends Controller {

 def places = Action {

    import play.api.libs.json._

      val list: List[Place] = {
        List(
          Place(
            "Sandleford",
            Location(51.377797, -1.318965)
          ),
          Place(
            "Watership Down",
            Location(51.235685, -1.309197)
          )
        )
      }


    import JsonStuff._

    Ok(Json.toJson(list))

}

我不得不:

  1. 将案例 类 移出 - 让它们独立存在
  2. 删除Place对象使list独立存在

否则我有:未找到未应用的函数错误。 (known limitations)

  1. 和放置 implicit val ..writers 的顺序确实很重要 - Place 应该知道 Location .. 因为那些作者是宏.. 就像在 JS 中一样 :) heh.

否则你会得到 NullPotinter 异常

(对我来说有点复杂)