gpt4 book ai didi

xml - Scala 使用 JSON 和/或 XML 模板

转载 作者:数据小太阳 更新时间:2023-10-29 01:57:22 24 4
gpt4 key购买 nike

我正在使用 Scalatra,但这个问题对任何 Scala 编程都应该有效。我来自 Ruby on Rails 背景。简而言之,使用 XML Builder 或 jsonbuilder ( https://github.com/rails/jbuilder ) 等模板系统,我可以通过创建如下模板完全控制 RESTful API 中的 JSON 或 XML 输出:

Jbuilder.encode do |json|
json.content format_content(@message.content)
json.(@message, :created_at, :updated_at)

json.author do
json.name @message.creator.name.familiar
json.email_address @message.creator.email_address_with_name
json.url url_for(@message.creator, format: :json)
end

if current_user.admin?
json.visitors calculate_visitors(@message)
end

json.comments @message.comments, :content, :created_at

json.attachments @message.attachments do |attachment|
json.filename attachment.filename
json.url url_for(attachment)
end
end

这里的理想是,我把一个@message放在一起具有 Controller +操作中所需的任何逻辑的对象。这将传递给具有逻辑的模板,例如 if current_user.admin?包括一些东西,否则不要。

Scala 或 Scalatra 中可用于执行类似操作的等效工具是什么?我知道一个serializer将使我覆盖从特定模型生成的 JSON 或 XML,但这在 Ruby 中与覆盖 as_json 相同(如果我错了请纠正我)或 as_xml .然而,有时模板要复杂得多,包括多个模型、特定的数据结构、特定的数据排序等。这就是我需要的灵 active 。当前是否有允许在 Scala/Scalatra 环境中进行此类模板化的工具?

最佳答案

不幸的是,我不知道有什么真正好的库可以在 XML 中执行此操作(尽管 Anti-Xml 值得一看)。但是有这样的 Json 库,它是 PlayJson使用 play json,你基本上可以做任何你可以用 Ruby 的 JsBuilder 做的事情,除了一些范式差异:

  1. Scala 试图尽可能地发挥功能,许多库使用不可变的数据结构进行操作。玩json也不异常(exception)。这意味着你不能只是改变json树深处的一些值,你需要重建整个json对象

  2. Scala 是一种静态类型语言。这很好,因为编译器会检查所有类型签名的正确性,除非我们必须提供这些签名。

示例代码:

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.", "david@heinemeierhansson.com", "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))
}

}

注意 attachmentFormat - 它由 scala 宏生成以与案例类定义相匹配。在我的项目中,我从来没有写过一个单独的手动格式覆盖编译器为我生成所有格式!但如果需要,我可以。很好的例子是 jodaTimeWrites - 默认的 jodaTimeFormat 将生成更适合机器处理的 long 值,但我已经用我自己的隐式格式覆盖它以匹配 ruby​​ 的示例。

上面的代码产生如下输出:

{
"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" : "david@heinemeierhansson.com",
"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"
} ]
}

现在我得到的不是 21 行 ruby​​ 代码,而是 33 行 scala 的某种程度上更复杂的映射(没有案例类)。为什么要输入更多?因为现在我非常确定,当我传递 Comment 而不是 Attachment 时,我会得到编译器错误,或者当我的同事错误地将 joda.time.DateFormat 更改为java.util.DateFormat 他会收到错误而不是一些乱码。

关于xml - Scala 使用 JSON 和/或 XML 模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17350926/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com