Scala 在Lift框架中,这是处理RESTful-like URL的正确方法吗?
如果我有一个类似{id}的URL,并且我希望{id}转换为一个参数,而不是URL路径部分 通过创建一个包含重写请求的菜单是最好的方法吗?因为如果我有很多像这样的URL模式,我发现它只是一个小样板Scala 在Lift框架中,这是处理RESTful-like URL的正确方法吗?,scala,lift,Scala,Lift,如果我有一个类似{id}的URL,并且我希望{id}转换为一个参数,而不是URL路径部分 通过创建一个包含重写请求的菜单是最好的方法吗?因为如果我有很多像这样的URL模式,我发现它只是一个小样板 val menu = Menu(new Loc[Unit] { override def name = "Test" override def text = "Test" override def link = (List ("Test"), true) overrid
val menu = Menu(new Loc[Unit] {
override def name = "Test"
override def text = "Test"
override def link = (List ("Test"), true)
override def params = Nil
override def defaultValue = Full(())
def isTarget (path: ParsePath) = path match {
case ParsePath (List("Test", "edit", id), _, _, _) => true
case _ => false
}
override def rewrite = Full ( NamedPF("Test") {
case RewriteRequest (path, _, _) if isTarget(path) =>
RewriteResponse(List("Test", "edit"),
Map("id" -> "1024")) -> ()
})
})
为什么要将其更改为查询参数?是技术原因还是框架原因
{id}在我的视图中属于URI路径,它标识一个唯一的资源,我喜欢将此信息保存在路径中。URI可以是任何类型的字符串(因此查询参数也可以工作),但我会尽可能地为URI建模,使其与资源id尽可能一致。对不起,上面的注释非常混乱
问题是,如果我在webapp/Test下有一个名为edit.html的模板,这就是我用来编辑项目的模板 我有一个菜单实例,如下所示:
Menu (Loc("Test", List("Test") -> true, "Test"))
在你的boot.scala中,它将只匹配URL,而不是类似的东西。你需要以下内容(来自实际工作代码!)注意,每个重写响应路径必须在你的站点地图中
LiftRules.rewrite.append {
case RewriteRequest(ParsePath(List("shopInfo", "view", id), _, _, _), _, _) => RewriteResponse("shopInfo" :: "view" :: Nil, Map("id" -> id))
case RewriteRequest(ParsePath(List("shopInfo", "orders", id), _, _, _), _, _) => RewriteResponse("shopInfo" :: "orders" :: Nil, Map("id" -> id))
case RewriteRequest(ParsePath(List("shopInfo", "sync", id), _, _, _), _, _) => RewriteResponse("shopInfo" :: "sync" :: Nil, Map("id" -> id))
case RewriteRequest(ParsePath(List("shopInfo", "delete", id), _, _, _), _, _) => RewriteResponse("shopInfo" :: "delete" :: Nil, Map("id" -> id))
case RewriteRequest(ParsePath(List("shopInfo", "edit", id), _, _, _), _, _) => RewriteResponse("shopInfo" :: "edit" :: Nil, Map("id" -> id))
}
谢谢你的回复 我最想要的是这些重写的东西和菜单紧密结合,所以我可以在我的模型类中设置它们,比如CRUDify trait 最后,我自己创建了一个Loc的子类来处理这些重写规则,我发现它工作得很好,使事情变得更简单(至少对我来说),所以我在这里发布了代码 如果有人需要,请随意复制
/**
* A RESTful-like URL handling Loc
*
* If you have the following templates:
*
* * webapps/item/edit.html
* * webapps/item/view.html
*
* You want the following URL map to corresponding template with
* last path component as a S parameter.
*
* http://localhost/item/edit/1 to http://localhost/item/edit
* http://localhost/item/view/1 to http://localhost/item/view
*
* You could create a Menu with this Loc class in your Model object.
*
* <code>
* object Item extends Item with LongKeyedMetaMapper[Item]
* {
* // Other methods here...
*
* def menu () {
*
* // What methods do we have?
* val methods = List ("view", "edit")
*
* val parameterName = "itemID"
* val itemLoc = new RESTfulLoc("Item", List("item"), "Item",
* methods, parameterName)
*
* Menu (itemLoc)
* }
* }
* </code>
*
* Now add the menu to SiteMap in Boot.boot
*
* <code>
* class Boot {
* def boot () {
*
* val entries = Item.menu :: Nil
*
* LiftRules.setSiteMap(SiteMap(entries:_*))
* }
* }
* </code>
*
*
* Finally, You could access the parameter in your snippet with
* S.param("itemID")
*
*/
class RESTfulLoc (val name: String, val path: List[String],
val text: LinkText[Unit], val methods: List[String],
val parameterName: String,
val locParams: LocParam[Unit]*) extends Loc[Unit]
{
override val defaultValue = Full(())
override val params = locParams.toList
override val link: Link[Unit] = (List(path.first), true)
def this (name: String, path: List[String], text: LinkText[Unit],
methods: List[String], locParams: LocParam[Unit]*) =
{
this (name, path, text, methods, "id", locParams:_*)
}
private def isTarget (path: ParsePath) =
{
path.partPath -- this.path match {
case List (action, id) => {
(methods contains action) && id != "index"
}
case _ => false
}
}
override def rewrite = Full (NamedPF("RESTfulLoc")
{
case RewriteRequest (path, _, _) if isTarget(path) => {
val parameter = path.partPath.last
val action = path.partPath.init
val data = Map (parameterName -> parameter)
RewriteResponse(action, data) -> ()
}
})
}
我无意中发现了这篇文章,因为我有同样的问题。Jim Barrows给出的答案是正确的(也是最简单的),但如果没有任何解释,我很难探究代码在做什么。Jim的解决方案工作原理的详细解释可以在Lift book online()中找到。查看第3.12节,标题为“URL重写”,该节指导您逐步了解如何构建RESTful URL 无论如何,应该不需要编写自定义Loc来实现所需的效果
祝你好运 问题是,如果我在webapp/Test下有一个名为edit.html的模板,这就是我用来编辑项目的模板。我有一个如下的菜单实例:Menu(Loc(“Test”,List(“Test”)->true,“Test”))它只匹配类似URL的内容,而不是类似URL的内容