2014-08-27 62 views
2

在普通的Play应用程序中,我有以下情形。Play Framework:表单验证失败后不要更改URL

路由文件看起来像这样:

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 - 未找到)。

也许这只是我,但我觉得这种讨厌和浏览一些GitHub项目,我找不到一个好的解决方案,这种情况。

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

...在这种情况下,一切工作正常:如果第二路径被改写为

事业事情会简单得多。但从REST的角度来看,这也感觉不太好。这同样适用于更新场景(具有GET/accounts /:id/update与PUT/accounts /:id)。

有没有指导如何处理?我从错误的角度来看问题还是完全没有问题?(从实际的角度来看)?

+0

请问您能说清楚一下是什么意思吗?但是从REST的角度来看,这也不是很好吗? – 2014-08-27 10:48:02

+0

当然。我希望通过对/ accounts(而不是/ accounts/new)执行POST来创建新的帐户资源,因为这'感觉不错',即通过查看路由定义可以清楚语义。 必须执行POST到/ accounts/new可能会混淆其他客户端,如果他们使用相同的API。 正如我所说,也许这并不像我想的那么严重。 – alexhanschke 2014-08-27 10:56:57

回答

2

由于已经创建了新地址的请求,因此无法离开先前的网址。控制器仅为请求的资源提供响应。要转到以前的URL,只能在验证失败的情况下进行重定向,但是您会以这种方式丢失错误,因此这不是解决方案。

我建议使用相同的URL映射两个动作。这样你就可以解决浏览器重新加载的问题。

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

+0

感谢丹尼尔 - 我也想过重定向,你说得对,这不是真正的解决方案,因为我必须跟踪上下文(也许使用闪存范围或其他)。 因此,最终我可能会使用相同的URL,但我想听到更多的想法。 – alexhanschke 2014-08-27 11:58:37