tiếc là tôi không biết bất kỳ thư viện thực sự tốt để làm điều này trong XML (mặc dù Anti-Xml là giá trị tham gia). Nhưng cũng có những thư viện đó cho Json và đó là PlayJson Với vở kịch json bạn có thể làm về cơ bản tất cả mọi thứ bạn có thể làm với JsBuilder Ruby, ngoại trừ một số khác biệt mô hình:
Scala cố gắng để được như chức năng càng tốt và nhiều nhiều thư viện hoạt động với cấu trúc dữ liệu không thể thay đổi. Chơi json không phải là ngoại lệ. Điều này có nghĩa là bạn không thể chỉ cần thay đổi một số giá trị sâu trong cây json, bạn cần phải tạo lại toàn bộ đối tượng json
Scala là một ngôn ngữ được nhập tĩnh. Điều này là tuyệt vời, bởi vì trình biên dịch kiểm tra tất cả các chữ ký kiểu cho tính chính xác, ngoại trừ chúng ta phải cung cấp các chữ ký đó.
Dưới đây là mã ví dụ:
import org.joda.time.DateTime
import org.joda.time.format.DateTimeFormat
case class Attachment(fileName: String, url: String)
case class Author(name: String, email: String, url: String)
case class Comment(content: String, created_at: DateTime)
case class Post(author: Author, content: String, attachments: List[Attachment], comments: List[Comment], created_at: DateTime, updated_at: DateTime)
object Main {
import play.api.libs.json._
import play.api.libs.functional.syntax._
val isAdmin = true
def calculateVisits(post: Post) = 35
implicit val jodaTimeWrites: Writes[DateTime] = new Writes[DateTime] {
def writes(c: DateTime): JsValue = {
Json.toJson(c.toString(DateTimeFormat.fullDateTime()))
}
}
implicit val attachmentFormat = Json.format[Attachment]
implicit val authorWrites: Writes[Author] = (
(__ \ "name").write[String] and
(__ \ "email").write[String] and
(__ \ "url").write[String]) { unlift(Author.unapply) }
implicit val commentWrites: Writes[Comment] = (
(__ \ "content").write[String] and
(__ \ "created_at").write[DateTime]) { unlift(Comment.unapply) }
implicit val postWrites: Writes[Post] = (
(__ \ "content").write[String] and
(__ \ "created_at").write[DateTime] and
(__ \ "updated_at").write[DateTime] and
(__ \ "author").write[Author] and
(__ \ "visitors").write[Option[Int]] and
(__ \ "comments").write[List[Comment]] and
(__ \ "attachments").write[List[Attachment]]) { post: Post =>
(
post.content,
post.created_at,
post.updated_at,
post.author,
if (isAdmin) Some(calculateVisits(post)) else None,
post.comments,
post.attachments)
}
def main(args: Array[String]): Unit = {
val post = Post(
Author("David H.", "[email protected]", "http://example.com/users/1-david.json"),
"<p>This is <i>serious</i> monkey business</p>",
List(
Attachment("forecast.xls", "http://example.com/downloads/forecast.xls"),
Attachment("presentation.pdf", "http://example.com/downloads/presentation.pdf")),
List(
Comment("Hello everyone!", new DateTime()),
Comment("To you my good sir!", new DateTime())),
new DateTime(),
new DateTime())
Console println (Json prettyPrint (Json toJson post))
}
}
Thông báo các attachmentFormat
- nó được tạo ra bởi các macro scala để được xuất hiện với định nghĩa ca bệnh lớp. Trong dự án của tôi, tôi chưa từng viết một trình biên dịch ghi đè định dạng thủ công nào tạo ra tất cả các định dạng cho tôi! Nhưng tôi có thể Nếu tôi cần. Ví dụ tốt là jodaTimeWrites
- mặc định jodaTimeFormat sẽ tạo ra giá trị lâu dài phù hợp hơn cho việc xử lý máy, nhưng tôi đã ghi đè nó bằng định dạng ẩn của riêng tôi để phù hợp với mẫu của ruby.
Đoạn mã trên tạo ra sau đầu ra:
{
"content" : "<p>This is <i>serious</i> monkey business</p>",
"created_at" : "Friday, July 5, 2013 4:19:42 PM +03:00",
"updated_at" : "Friday, July 5, 2013 4:19:42 PM +03:00",
"author" : {
"name" : "David H.",
"email" : "[email protected]",
"url" : "http://example.com/users/1-david.json"
},
"visitors" : 35,
"comments" : [ {
"content" : "Hello everyone!",
"created_at" : "Friday, July 5, 2013 4:19:42 PM +03:00"
}, {
"content" : "To you my good sir!",
"created_at" : "Friday, July 5, 2013 4:19:42 PM +03:00"
} ],
"attachments" : [ {
"fileName" : "forecast.xls",
"url" : "http://example.com/downloads/forecast.xls"
}, {
"fileName" : "presentation.pdf",
"url" : "http://example.com/downloads/presentation.pdf"
} ]
}
Bây giờ thay vì 21 dòng mã ruby tôi có 33 dòng của scala bằng cách nào đó ánh xạ phức tạp hơn (không có trường hợp lớp). Tại sao lại nhập nhiều hơn? Bởi vì bây giờ tôi đã chết chắc chắn rằng khi tôi vượt qua Comment
thay vì Attachment
tôi sẽ nhận được lỗi biên dịch, hoặc khi đồng nghiệp của tôi sẽ thay đổi do nhầm lẫn joda.time.DateFormat để java.util.DateFormat anh ta sẽ nhận được lỗi thay vì một số sai ngữ pháp .