【问题标题】:Rendering JSON with Play! and Scala使用 Play 渲染 JSON!和斯卡拉
【发布时间】:2012-11-15 16:55:20
【问题描述】:

我有一个关于从 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)))
  }
} 

【问题讨论】:

    标签: json scala playframework playframework-2.0


    【解决方案1】:

    我真的建议升级到玩 2.1-RC1 因为在这里,JSON writer/readers 的定义非常简单(更多细节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))))
    

    read示例(我举了我的示例,通过从正文读取 json 来创建实体)请注意此处使用的 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 变得非常简单。

    【讨论】:

      【解决方案2】:

      如果你使用的是 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)
      

      【讨论】:

        【解决方案3】:

        我一直在我的项目中使用 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)
        ...
        

        【讨论】:

          【解决方案4】:

          其实这很简单。首先导入:

          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$

          【讨论】:

            【解决方案5】:

            在你的情况下,我会使用 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)
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2017-03-17
              • 1970-01-01
              • 1970-01-01
              • 2017-10-23
              • 2013-11-06
              • 1970-01-01
              • 2018-03-21
              相关资源
              最近更新 更多