2014-08-27 48 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