2012-11-27 41 views
6

Tôi có một câu hỏi đơn giản về việc hiển thị đối tượng JSON từ một lớp Scala. Tại sao tôi phải thực hiện deserializer (đọc, viết).Hiển thị JSON bằng Play! và Scala

Tôi có lớp trường hợp sau đây:

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

Và trong bộ điều khiển của tôi:

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

Json.toJson(milo); 

tôi nhận được lỗi biên dịch: Không Json deserializer tìm thấy cho loại models.User. Hãy thử triển khai một Writes hoặc định dạng tiềm ẩn cho loại này.

Trong dự án trước đây của tôi, tôi đã phải thực hiện một người đọc, đối tượng nhà văn trong lớp cho nó để làm việc và tôi thấy nó rất khó chịu.

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

Trả lời

3

Nếu bạn đang sử dụng chơi 2.0.x bạn có thể làm

import com.codahale.jerkson.Json._ 

generate(milo) 

tạo sử dụng phản ánh để làm điều đó.

Trong phiên bản 2.1, bạn có thể sử dụng Json.writes để tạo macro cho đối tượng tiềm ẩn mà bạn đã tạo. Không cần thời gian chạy phản chiếu!

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

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

tôi thực sự khuyên bạn nên nâng cấp lên chơi 2.1-RC1 vì ở đây, tác giả JSON/độc giả là rất đơn giản để được xác định (chi tiết here)

Nhưng để giúp bạn tránh một số sai sót, Tôi sẽ cung cấp cho bạn một gợi ý về nhập khẩu: - chỉ sử dụng các mục nhập này! (Chú ý rằng json.Reads không được bao gồm)

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

và bạn chỉ phải viết mã này cho ghi/đọc lớp học của bạn đến/từ Json (tất nhiên bạn sẽ có User thay vì Address:

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

Giờ đây, họ sẽ được sử dụng tự động:

Ví dụ về ghi:

Ok(Json.toJson(entities.map(s => Json.toJson(s)))) 

Ví dụ về đọc (Tôi đưa ví dụ của tôi làm POST để tạo ra một thực thể bằng cách đọc json từ cơ thể) xin vui lòng nhận thấy addressReads sử dụng ở đây

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

Tóm lại, họ đã cố gắng (và succeded) để làm mọi thứ rất đơn giản liên quan đến JSON.

0

Tôi đã sử dụng jerkson (về cơ bản là trình bao bọc cho jackson) trong dự án của tôi để chuyển đổi các đối tượng thành chuỗi json.

Cách đơn giản nhất để làm điều đó là:

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

Nếu bạn cần phải cấu hình ObjectMapper (ví dụ: thêm tùy chỉnh serializer/deserializer, cấu hình định dạng đầu ra, vv), bạn có thể làm điều đó bằng cách tạo đối tượng mở rộng lớp 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) 
} 

Để sử dụng nó trong mã của bạn:

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

Trong thực tế, điều này rất đơn giản. Thứ nhất nhập khẩu:

import play.api.libs.json._ 

Nhờ vào thực tế, rằng tài khoản là một lớp trường hợp bạn có thể tự động tạo Json viết bằng Json.writes []:

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

tôi đã không tìm thấy nó trong các tài liệu , nhưng đây là liên kết tới api: http://www.playframework.com/documentation/2.2.x/api/scala/index.html#play.api.libs.json.Json $

0

Trong trường hợp của bạn, tôi sẽ sử dụng macro 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) 
Các vấn đề liên quan