在play框架文档中,有两种不同的方法来处理带有验证错误的操作:
if (validation.hasErrors()) {
params.flash(); // add http parameters to the flash scope
validation.keep(); // keep the errors for the next request
index();
}
if (validation.hasErrors()) {
render("@form", post);
}
最好的方法是什么?渲染还是重定向?
答案 0 :(得分:7)
两种方法都有利弊。
我个人的偏好是使用重定向方法,原因是浏览器URL正确指出了您在应用程序中的位置。例如,如果您的索引页面调用登录操作,如果您不使用重定向,那么当您实际在索引页面上有错误时,浏览器URL将显示登录。
但是,这种方法存在问题。要实现重定向并保留验证错误消息,您需要使用validation.keep()
和params.flash()
(有关详细信息,请参阅此post here),以便为下一个请求保留验证错误。这是在幕后通过将验证错误和用户输入的参数存储在Cookie中来实现的(以确保Play保持无状态)。您可能已经知道,HTTP规范将Cookie限制为4Kb,因此如果您输入的数据大于4Kb(这对于您输入大块文本的表单可能是这样),那么您的Cookie会溢出,你会丢失数据。
Play使用的原始方法是重定向方法,但由于Cookie限制,第二种方法作为解决方法专门添加到文档中。
第三种,可能更清晰的选择是使用javascript从客户端执行验证,该javascript使用AJAX来调用某些服务器端逻辑。在samples-and-test/validation
示例应用程序的第10个示例中可以看到此示例。
答案 1 :(得分:2)
我更愿意再次渲染表单模板,因为我认为重定向在这种情况下没用。如果用户按F5,他仍然可以再次发送相同的数据。用户唯一的问题是取消操作。
为了避免COdemwnci提到的url问题,你可以在routes.conf中使用以下技巧
GET /customer/edit CustomerController.load()
POST /customer/edit CustomerController.save()
然后你总是有一个干净的URL。
答案 2 :(得分:1)
我也会去重定向,以便拥有干净的网址。但是,从一个变体切换到另一个变体通常需要的不仅仅是保持验证结果和http参数,即处理所有其他渲染参数。
我最近的例子是表单验证和地址更正:
前
public static void step2(@Valid Address address)
{
AddressResult result = ....; // perform address check
if (result.isCorrected())
{
validation.addError("address.streetAndHouseNumber", "Street has been corrected.");
address.streetAndHouseNumber = result.getStreet();
render("step1.html", address);
}
... // continue
}
后
public static void step2(@Valid Address address)
{
AddressResult result = ....; // perform address check
if (result.isCorrected())
{
validation.addError("address.streetAndHouseNumber", "Street has been corrected.");
// ----- note this line --------
params.put("address.streetAndHouseNumber", result.getStreet());
// -----------------------------
params.flash();
validation.keep();
step1();
}
... // continue
}
虽然可以在变体2中轻松填充本地范围变量,但我们需要更新http参数resp。直接写在闪存范围内。
任何具有适当抽象级别的人都可以轻松地在两种变体之间切换?