在一个普通的 Play 应用程序中,我有以下场景。
路由文件如下所示:
GET /accounts/add controllers.Accounts.add()
POST /accounts controllers.Accounts.create()
第一条路线会产生一个 View ,我可以在其中添加新帐户。提交新帐户的表单如下所示:
@helper.form(action = routes.Accounts.create()) {...}
现在 Controller 将输入绑定(bind)到表单并检查是否有任何验证错误:
public static Result create() {
Form<Account> form = Form.form(Account.class).bindFromRequest();
if (form.hasErrors()) {
return badRequest(views.html.account.add.render(form));
}
...
}
现在的问题是,客户端将看到相同的 View 以及一些附加的错误消息。然而,与此同时,URL 已从 http://example.com/accounts/add 更改为至http://example.com/accounts .
如果客户端现在重新加载浏览器,则会调用 GET http://example.com/accounts (在这种情况下甚至没有映射 - 因此得到 404 - 未找到)。
也许只有我这么认为,但我发现这种情况很烦人,并且浏览了一些 GitHub 项目,我找不到针对这种情况的良好解决方案。
当然,如果将第二条路由重写为:
,事情会简单得多POST /accounts/add controllers.Accounts.create()
...在这种情况下一切正常。但从 REST 的角度来看,这感觉也不好。这同样适用于更新场景(GET/accounts/:id/update 与 PUT/accounts/:id)。
有关于如何处理这个问题的指南吗?我是否弄错了什么,或者这根本没有问题(从务实的角度来看)?
最佳答案
无法保留之前的 URL,因为已经发出了新地址的请求。 Controller 仅为所请求的资源提供响应。要转到上一个 URL,您只能在验证失败的情况下进行重定向,但这样会丢失错误,因此这不是解决方案。
我建议将这两个操作映射到相同的 URL。这样您就可以解决浏览器重新加载的问题。
如果您为非浏览器的 http 客户端创建 REST 服务,您可能希望提供与简单 http 页面不同的响应。特定客户端的操作分离可能是保持 REST API 清洁和浏览器用户满意的一个很好的解决方案。
关于rest - Play Framework : Don't change URL after form validation failed,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25523792/