【问题标题】:Play Framework: Don't change URL after form validation failedPlay Framework:表单验证失败后不要更改 URL
【发布时间】:2014-10-20 20:09:07
【问题描述】:

在一个普通的 Play 应用程序中,我有以下场景。

如下所示的路由文件:

GET        /accounts/add        controllers.Accounts.add()
POST       /accounts            controllers.Accounts.create()

第一条路线导致我可以在其中添加新帐户的视图。提交新帐户的表单如下所示:

@helper.form(action = routes.Accounts.create()) {...}

现在控制器将输入绑定到表单并检查任何验证错误:

public static Result create() {
    Form<Account> form = Form.form(Account.class).bindFromRequest();
    if (form.hasErrors()) {
        return badRequest(views.html.account.add.render(form));
    }
    ...
}

现在问题是,客户端将看到相同的视图以及一些额外的错误消息。但是,同时 URL 已从 http://example.com/accounts/add 更改为 http://example.com/accounts

如果客户端现在重新加载浏览器,这将调用 GET http://example.com/accounts(在这种情况下甚至没有映射 - 因此得到 404 - Not Found)。

也许只有我一个人,但我觉得这种烦人,浏览一些 GitHub 项目我找不到适合这种情况的好解决方案。

当然,如果将第二条路线重写为:

POST        /accounts/add        controllers.Accounts.create()

... 在这种情况下,一切正常。但从 REST 的角度来看,这也感觉不好。这同样适用于更新场景(具有 GET /accounts/:id/update 与 PUT /accounts/:id)。

是否有关于如何处理此问题的指南?我是不是搞错了,或者这根本没有问题(从务实的角度来看)?

【问题讨论】:

  • 您能否澄清一下您所说的“但从 REST 的角度来看,这也感觉不好”是什么意思?
  • 当然。我希望通过对 /accounts(而不是 /accounts/new)执行 POST 来创建新帐户资源,因为这“感觉正确”,即通过查看路由定义可以清楚地了解语义。如果其他客户端使用相同的 API,则必须对 /accounts/new 执行 POST 可能会使他们感到困惑。正如我所说,也许这并没有我想象的那么严重。

标签: rest playframework playframework-2.0


【解决方案1】:

无法离开之前的网址,因为已经提出了新地址的请求。控制器只为请求的资源提供响应。要转到上一个 URL,您只能在验证失败的情况下进行重定向,但那样会丢失错误,因此这不是解决方案。

我建议将这两个操作映射到同一个 URL。这样你就可以解决浏览器重新加载的问题。

如果您为非浏览器的 http 客户端创建 REST 服务,您可能希望提供与简单 http 页面不同的响应。特定客户端的操作分离可能是保持 REST API 清洁和浏览器用户满意的一个很好的解决方案。

【讨论】:

  • 谢谢丹尼尔 - 我也考虑过重定向,你是对的,这不是真正的解决方案,因为我必须跟踪上下文(可能使用 flash 范围或其他东西)。所以最终我可能会使用相同的 URL,但我想听听更多关于它的想法。
猜你喜欢
  • 1970-01-01
  • 2015-07-19
  • 2016-02-08
  • 1970-01-01
  • 2013-07-25
  • 2014-11-01
  • 2013-04-15
  • 2012-11-21
  • 1970-01-01
相关资源
最近更新 更多