2012-11-27 69 views
6

我有一個關於從Scala類中呈現JSON對象的簡單問題。爲什麼我必須實現解串器(讀,寫)。使用Play呈現JSON!和斯卡拉

我有以下的情況下類:

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

而且在我的控制器:

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

Json.toJson(milo); 

我得到的編譯錯誤:沒有Json的解串器發現類型models.User。嘗試爲此類型實現隱式Writes或Format。

在我以前的項目中,我必須在類中實現一個讀寫器對象,以便它能夠工作,並且我覺得它很煩人。

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

回答

3

如果您使用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) 
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] 

現在,他們將被自動應用於:

實施例的 寫入

舉例 閱讀

(我把我做的POST用於創建實體的例子通過讀取體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."))) 
     } 
} 

使用總之,他們試圖(和succeded),使關於JSON的事情很簡單。

0

我一直在我的項目中使用jerkson(基本上是傑克遜的包裝)將對象轉換爲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) 
... 
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)