[英]JSR-303 / Spring MVC - validate conditionally using groups
I worked out a concept to conditionally validate using JSR 303 groups. 我提出了一个概念,可以有条件地使用JSR 303组进行验证。 "Conditionally" means that I have some fields which are only relevant if another field has a specific value.
“有条件地”表示我有一些仅在另一个字段具有特定值的情况下才相关的字段。
Example: There is an option to select whether to register as a person or as a company. 示例:有一个选项可以选择是注册为个人还是公司。 When selecting company, the user has to fill a field containing the name of the company.
选择公司时,用户必须填写包含公司名称的字段。
Now I thought I use groups for that: 现在我认为我可以使用组:
class RegisterForm
{
public interface BasicCheck {}
public interface UserCheck {}
public interface CompanyCheck {}
@NotNull(groups = BasicCheck.class)
private Boolean isCompany
@NotNull(groups = UserCheck.class)
private String firstName;
@NotNull(groups = UserCheck.class)
private String lastName;
@NotNull(groups = CompanyCheck.class)
private String companyName;
// getters / setters ...
}
In my controller, I validate step by step depending on the respective selection: 在我的控制器中,我会根据各自的选择逐步验证:
@Autowired
SmartValidator validator;
public void onRequest(@ModelAttribute("registerForm") RegisterForm registerForm, BindingResult result)
{
validator.validate(registerForm, result, RegisterForm.BasicCheck.class);
if (result.hasErrors()
return;
// basic check successful => we can process fields which are covered by this check
if (registerForm.getIsCompany())
{
validator.validate(registerForm, result, RegisterForm.CompanyCheck.class)
}
else
{
validator.validate(registerForm, result, RegisterForm.UserCheck.class);
}
if (!result.hasErrors())
{
// process registration
}
}
I only want to validate what must be validated. 我只想验证必须验证的内容。 If the user selects "company" fills a field with invalid content and then switches back to "user", the invalid company related content must be ignored by the validator.
如果用户选择“公司”,则使用无效内容填充字段,然后切换回“用户”,验证程序必须忽略与公司相关的无效内容。 A solution would be to clear those fields using Javascript, but I also want my forms to work with javascript disabled.
一种解决方案是使用Javascript清除这些字段,但我也希望表单在禁用javascript的情况下工作。 This is why I totally like the approach shown above.
这就是为什么我完全喜欢上面显示的方法的原因。
But Spring breaks this idea due to data binding. 但是由于数据绑定,Spring打破了这个想法。 Before validation starts, Spring binds the data to registerForm.
在验证开始之前,Spring将数据绑定到registerForm。 It adds error to
result
if, for instance, types are incompatible (expected int-value, but user filled the form with letters). 例如,如果类型不兼容(预期的整数值,但用户用字母填充表格),则会在
result
增加错误。 This is a problem as these errors are shown in the JSP-view by <form:errors />
tags 这是一个问题,因为这些错误在
<form:errors />
标记在JSP视图中显示
Now I found a way to prevent Spring from adding those errors to the binding result by implementing a custom BindingErrorProcessor
. 现在,我找到了一种方法,可以通过实现自定义
BindingErrorProcessor
来防止Spring将这些错误添加到绑定结果中。 If a field contains null
I know that there was a validation error. 如果字段包含
null
我知道存在验证错误。 In my concept null
is not allowed - every field gets annotated with @NotNull
plus the respective validation group. 在我的概念
null
是不允许的-每场得到带注释@NotNull
加上相应的验证组。
As I am new to Spring and JSR-303 I wonder, whether I am totally on the wrong path. 当我刚接触Spring和JSR-303时,我想知道自己是否完全走错了道路。 The fact that I have to implement a couple of things on my own makes me uncertain.
我必须自己执行几件事,这使我不确定。 Is this a clean solution?
这是一个干净的解决方案吗? Is there a better solution for the same problem, as I think this is a common problem?
我认为这是一个普遍的问题,对于同一问题是否有更好的解决方案?
EDIT 编辑
Please see my answer here if you are interested in my solution in detail: https://stackoverflow.com/a/30500985/395879 如果您对我的解决方案感兴趣,请在这里查看我的答案: https : //stackoverflow.com/a/30500985/395879
You are correct that Spring MVC is a bit picky in this regard,and it is a common problem. 您是正确的,Spring MVC在这方面有点挑剔,这是一个普遍的问题。 But there are work-arounds:
但是有解决方法:
Good luck! 祝好运!
I know this question is old, but I came upon it looking for an answer for a different situation. 我知道这个问题很旧,但是我遇到了这个问题,正在寻找其他情况的答案。
I think for your situation you could use inheritance for the forms and then use two controller methods: 我认为根据您的情况,您可以对表格使用继承,然后使用两种控制器方法:
The forms would look like this: 表格如下所示:
public class RegistrationForm
{
// Common fields go here.
}
public class UserRegistrationForm
extends RegistrationForm
{
@NotNull
private String firstName;
@NotNull
private String lastName;
// getters / setters ...
}
public class CompanyRegistrationForm
extends RegistrationForm
{
@NotNull
private String companyName;
// getters / setters ...
}
The controller methods would look like this: 控制器方法如下所示:
@RequestMapping(method = RequestMethod.POST, params = "isCompany=false")
public void onRequest(
@ModelAttribute("registerForm") @Valid UserRegistrationForm form,
BindingResult result)
{
if (!result.hasErrors())
{
// process registration
}
}
@RequestMapping(method = RequestMethod.POST, params = "isCompany=true")
public void onRequest(
@ModelAttribute("registerForm") @Valid CompanyRegistrationForm form,
BindingResult result)
{
if (!result.hasErrors())
{
// process registration
}
}
Notice that the @RequestMapping
annotations include a params
attribute so the value of the isCompany
parameter determines which method is called. 注意,
@RequestMapping
注释包括一个params
属性所以值isCompany
参数确定哪个方法被调用。
Also notice that the @Valid
annotation is place on the form
parameter. 还要注意,@
@Valid
批注位于form
参数上。
Finally, no groups are needed in this case. 最后,在这种情况下,不需要任何组。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.