使用Play渲染JSON!和斯卡拉

时间:2012-11-27 23:13:02

标签: json scala playframework playframework-2.0

我有一个关于从Scala类渲染JSON对象的简单问题。为什么我必须实现反序列化器(读,写)。

我有以下案例类:

case class User(firstname:String, lastname:String, age:Int)

在我的控制器中:

val milo:User = new User("Sam","Fisher",23);

Json.toJson(milo);

我收到编译错误:找不到类型models.User的Json反序列化器。尝试为此类型实现隐式写入或格式。

在我之前的项目中,我不得不在课堂上实现一​​个阅读器,编写器对象,以使其工作,我发现它非常烦人。

object UserWebsite {
  implicit object UserWebsiteReads extends Format[UserWebsite] {

    def reads(json: JsValue) = UserWebsite(
      (json \ "email").as[String],
      (json \ "url").as[String],
      (json \ "imageurl").as[String])

    def writes(ts: UserWebsite) = JsObject(Seq(
      "email" -> JsString(ts.email),
      "url" -> JsString(ts.url),
      "imageurl" -> JsString(ts.imageurl)))
  }
} 

5 个答案:

答案 0 :(得分:9)

我真的建议升级到2.1-RC1,因为在这里,JSON编写器/阅读器定义非常简单(更多细节here

但是为了帮助您避免一些错误,我会给你一个进口提示: - 仅使用这些进口! (注意不包括json.Reads)

import play.api.libs.json._
import play.api.libs.functional.syntax._
import play.api.libs.json.Writes._

你只需编写这段代码就可以在Json上写/读你的课程(当然你会User而不是Address

implicit val addressWrites = Json.writes[Address]
implicit val addressReads = Json.reads[Address]

现在,它们将自动使用:

的示例
Ok(Json.toJson(entities.map(s => Json.toJson(s))))

阅读的例子(我举例说明了通过从正文中读取json来创建实体的POST)请注意addressReads这里使用的

def create = Action(parse.json) { request =>
        request.body.validate(addressReads).map { entity =>
          Addresses.insert(entity)
          Ok(RestResponses.toJson(RestResponse(OK, "Succesfully created a new entity.")))
        }.recover { Result =>
          BadRequest(RestResponses.toJson(RestResponse(BAD_REQUEST, "Unable to transform JSON body to entity.")))
        }
}

总之,他们尝试(并成功)使JSON的事情变得非常简单。

答案 1 :(得分:3)

如果您使用的是Play 2.0.x,则可以

import com.codahale.jerkson.Json._

generate(milo)

生成使用反射来做到这一点。

在Play 2.1中,您可以使用Json.writes为您必须创建的隐式对象创建一个宏。不需要运行时反射!

import play.api.libs.json._
import play.api.libs.functional.syntax._

implicit val userWrites = Json.writes[User]
Json.toJson(milo)

答案 2 :(得分:0)

我一直在我的项目中使用jerkson(基本上是jackson的包装器)将对象转换为json字符串。

最简单的方法是:

import com.codehale.jerkson.Json._
...
generate(milo)
...

如果需要配置ObjectMapper(例如添加自定义序列化器/反序列化器,配置输出格式等),可以通过创建扩展com.codehale.jerkson.Json类的对象来实现。

package utils

import org.codehaus.jackson.map._
import org.codehaus.jackson.{Version, JsonGenerator, JsonParser}
import com.codahale.jerkson.Json
import org.codehaus.jackson.map.module.SimpleModule
import org.codehaus.jackson.map.annotate.JsonSerialize

object CustomJson extends Json {

  val module = new SimpleModule("CustomSerializer", Version.unknownVersion())

  // --- (SERIALIZERS) ---
  // Example:
  // module.addSerializer(classOf[Enumeration#Value], EnumerationSerializer)
  // --- (DESERIALIZERS) ---
  // Example:
  // module.addDeserializer(classOf[MyEnumType], new EnumerationDeserializer[MyEnumType](MyEnumTypes))

  mapper.setSerializationInclusion(JsonSerialize.Inclusion.NON_NULL)
  mapper.setSerializationConfig(mapper.getSerializationConfig.without(SerializationConfig.Feature.WRITE_NULL_MAP_VALUES))
  mapper.registerModule(module)
}

要在您的代码中使用它:

import utils.CustomJson._
...
generate(milo)
...

答案 3 :(得分:0)

事实上,这很简单。首先导入:

import play.api.libs.json._

由于这个事实,User是一个案例类,你可以使用Json.writes []自动创建Json写入:

val milo:User = new User("Millad","Dagdoni",23)
implicit val userImplicitWrites = Json.writes[User]
Json.toJson(milo)

我还没有在文档中找到它,但这里是api的链接:http://www.playframework.com/documentation/2.2.x/api/scala/index.html#play.api.libs.json.Json $

答案 4 :(得分:0)

在您的情况下,我使用JSON.format宏。

import play.api.libs.json._
implicit val userFormat = Json.format[User]
val milo = new User("Sam", "Fisher", 23)
val json = Json.toJson(milo)