理解路由优先级时遇到问题

时间:2015-05-12 08:47:05

标签: java playframework routing

我正在建立某种讨论板,在那里你可以提问并写答案。现在我遇到了路由问题,似乎错误地理解了它们。

我有一个名为index的主页,您可以在此处点击“提问”或其他按钮“写答案”。每个按钮都会指向另一个网页(askQuestion.scala.html或writeAnswer.scala.html),您可以在其中编写问题或答案。点击submit后,您将返回索引页面,其中新问题或答案将放入视图中。在后台,问题/答案被放入DB中。

我的 routes.conf

# Home page
GET     /                           controllers.Application.index()

#Questions
GET     /FrageStellen               controllers.Application.askQuestion()
POST    /                           controllers.Application.sendQuestion()

#Answers
GET     /AntwortGeben               controllers.Application.writeAnswer()
POST    /                           controllers.Application.sendAnswer()

但是当我输入答案时,它会被写入数据库的问题表中!这是因为问题路由在路由表中更高,因此它似乎首先被选中。

这违反了我对路由的理解,我认为路由包含一个3元组:HTTP-Method, Request Path, Call definition ...并且由于调用定义不同(sendQuestion()和sendAnswer()),正确的路由应该是使用?

为什么不是这样?

我已经阅读了documentation of the play framework中的路由并用Google搜索,但仍然不明白。

我也知道如何解决我的问题,但我想了解这里发生了什么。

修复1: 改变这个

POST    /                           controllers.Application.sendAnswer()

到这个

POST    /Antwort                    controllers.Application.sendAnswer()

缺点:这不再是主页(索引)了。看起来很奇怪。

修复2: 编写一种组合方法,用于将表单中的内容发送到索引。

缺点:我希望将方法分开,以便在我的项目中保持更好的结构。此外,我还必须查看问题是否被提出或者是否写出了答案,并且基于省略其中一个字段或使用另一个字段(答案有一个额外的questionID字段来链接问题的答案)。

那么,为什么这种情况会发生在路线上,哪些是最好的处理方法呢?

2 个答案:

答案 0 :(得分:1)

您应该发布到具有不同请求路径的操作,然后重定向到索引。这是Web开发中推荐的方法。

http://en.wikipedia.org/wiki/Post/Redirect/Get

答案 1 :(得分:1)

在Play中,每条路线都是路线方法(GET / POST)和路径(由静态部分和参数类型确定)的组合,所以如果你有两条相同类型和路径的路线只有第一个可以解析,即使你使用其他名称的param(但是同样的param类型),其他人也会被忽略。

在这种情况下,bar(String bar)方法赢得永远无法解决:

GET  /foo/:foo controllers.Application.foo(foo: String)
GET  /foo/:bar controllers.Application.bar(bar: String)

确保您不会破坏路线的最安全方法是使用始终成套的唯一路径:

GET     /                 controllers.Application.index()

GET     /FrageStellen     controllers.Application.askQuestion()
POST    /FrageStellen     controllers.Application.sendQuestion()

GET     /AntwortGeben     controllers.Application.writeAnswer()
POST    /AntwortGeben     controllers.Application.sendAnswer()

最后,如果您想在发布后转到根页面,则可以返回redirect()而不是ok()