6

我有一个关于从 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 反序列化器。尝试为此类型实现隐式写入或格式。

在我之前的项目中,我必须在类中实现一个 reader、writer 对象才能工作,我觉得这很烦人。

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)))
  }
} 
4

5 回答 5

9

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

但是为了帮助你避免一些错误,我会给你一个关于导入的提示: - 只使用这些导入!(注意 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 的事情变得非常简单。

于 2012-11-28T11:36:16.370 回答
3

如果您使用的是 play 2.0.x,您可以这样做

import com.codahale.jerkson.Json._

generate(milo)

generate 使用反射来做到这一点。

在 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)
于 2012-11-27T23:18:47.093 回答
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)
...
于 2012-11-29T14:41:41.620 回答
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 $

于 2014-04-04T07:08:36.770 回答
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)
于 2016-04-19T15:05:13.533 回答