为什么即使在引用站点地图中的链接后重写请求也不起作用?

时间:2011-08-09 00:43:12

标签: web-applications scala lift

我在Boot.boot()中有以下重写。这是基于Lift Wiki中URL Rewriting部分中的说明。

LiftRules.statefulRewrite.prepend(NamedPF("CreateAndEditRewrite") {
  case RewriteRequest(
        ParsePath("models" :: "createEdit" :: state :: Nil, _, _,_), _, _) => {
      Console.println("Rewriting path: models/createEdit/Create to createEdit.html")
      val rewriteResp = RewriteResponse(
        "models/createEdit" :: Nil, "html" // Use webapp/models/creteEdit.html
      )
      Console.println("Response refers to URL " + rewriteResp.path + " with parameters " + rewriteResp.params.toList.map(x => "" + x.key + "=" + x.value + ", "))
      rewriteResp

  }
})

为确保所有内容都可访问,请确保SiteMap允许使用以下行访问“models / createEdit / create”和“models / createEdit”。

val entries =
     Menu(Loc("models", List(""), "Models"),
         Menu(Loc("createEditM", List("models","createEdit","Create"), "[NEW]Create Model", loggedIn)),
         Menu(Loc("createEditMXX", List("models","createEdit"), "[NEW]Create Model", loggedIn)) ) ::
     User.sitemap

// Build SiteMap
LiftRules.setSiteMap(SiteMap(entries:_*))
LiftRules.passNotFoundToChain = true //if a URL isn't found pass responsability to the container

然而,第二个菜单选项有效,而第一个菜单选项为“HTTP ERROR 404” 在容器级别访问/ models / createEdit / Create时遇到问题。

控制台上出现以下println

Rewriting path: models/createEdit/Create to createEdit.html
Response refers to URL ParsePath(List(models/createEdit),html,true,false) with parameters List()
INFO - Service request (GET) /models/createEdit/Create returned 0, took 11 Milliseconds

表示重写被触发。

我正在使用Lift 2.4-M3和Scala 2.9.0-1。

任何人都知道这是什么问题?

感谢。

编辑:更改了代码示例并添加了控制台输出,以使更清晰的事情发生。

2 个答案:

答案 0 :(得分:2)

为了解决rwriting问题,我最终删除了重写规则并使用以下代码实现了自定义Loc对象。

package pt.cnbc.wikimodels.client

package object sitemapTweaks {
  import net.liftweb.common.Full
  import net.liftweb.http.{RewriteResponse, ParsePath, RewriteRequest}
  import net.liftweb.sitemap.Loc
  import net.liftweb.common.Box
  import net.liftweb.sitemap.Loc.{
  Link, LinkText, LocParam, Hidden
  }
  import net.liftweb.sitemap.Loc.If._
  import pt.cnbc.wikimodels.snippet.User
  import net.liftweb.sitemap.Loc._

  // verification if the user is logged
  val loggedIn = If(() => User.loggedIn_?, "You must be logged in.")

  object ModelPageLoc extends Loc[ModelPageState] {
    var state:ModelPageState = defaultValue.openTheBox
    def name: String = "CreateEDitWithState"

    def link = new Link[ModelPageState]("models" :: "createEdit" :: "Create" :: Nil)

    def text = "Model handling" + defaultValue

    def params: List[LocParam[ModelPageState]] = List(loggedIn)

    override def rewrite = Full({
      case RewriteRequest(ParsePath(List("models", "createEdit", _state), _, _, _), _, _) => {
        _state match {
          case "Create" => {
            state = Create
            (RewriteResponse(List("models", "createEdit")), Create)
          }
          case _ => {
            state = Edit
            (RewriteResponse(List("models", "createEdit")), Edit)
          }
        }
      }
    })
    def defaultValue: Box[ModelPageState] = Full(Create)
  }

  sealed abstract class ModelPageState

  case object Create extends ModelPageState

  case object Edit extends ModelPageState
}

实现此对象后,我只需要添加一个站点地图引用:

val entries =
     Menu(Loc("models", List(""), "Models"),
         Menu(Loc("createEditMXX", List("models","createEdit"), "[NEW]Create Model", loggedIn)),
         Menu(ModelPageLoc), //This line calls the customized Loc object
     User.sitemap

// Build SiteMap
LiftRules.setSiteMap(SiteMap(entries:_*))
LiftRules.passNotFoundToChain = true //if a URL isn't found pass responsability to the container

已经完成了!

答案 1 :(得分:1)

首先,不要使用重写内容。它的水平很低,通常没有必要。

如果您想要参数化菜单条目,请使用Menu.param。见http://simply.liftweb.net/index-3.2.html#toc-Subsection-3.2.7