繁体   English   中英

JSR-303 / Spring MVC-使用组有条件地验证

[英]JSR-303 / Spring MVC - validate conditionally using groups

我提出了一个概念,可以有条件地使用JSR 303组进行验证。 “有条件地”表示我有一些仅在另一个字段具有特定值的情况下才相关的字段。

示例:有一个选项可以选择是注册为个人还是公司。 选择公司时,用户必须填写包含公司名称的字段。

现在我认为我可以使用组:

  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 ...
  }

在我的控制器中,我会根据各自的选择逐步验证:

  @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
     }
  }

我只想验证必须验证的内容。 如果用户选择“公司”,则使用无效内容填充字段,然后切换回“用户”,验证程序必须忽略与公司相关的无效内容。 一种解决方案是使用Javascript清除这些字段,但我也希望表单在禁用javascript的情况下工作。 这就是为什么我完全喜欢上面显示的方法的原因。

但是由于数据绑定,Spring打破了这个想法。 在验证开始之前,Spring将数据绑定到registerForm。 例如,如果类型不兼容(预期的整数值,但用户用字母填充表格),则会在result增加错误。 这是一个问题,因为这些错误在<form:errors />标记在JSP视图中显示

现在,我找到了一种方法,可以通过实现自定义BindingErrorProcessor来防止Spring将这些错误添加到绑定结果中。 如果字段包含null我知道存在验证错误。 在我的概念null是不允许的-每场得到带注释@NotNull加上相应的验证组。

当我刚接触Spring和JSR-303时,我想知道自己是否完全走错了道路。 我必须自己执行几件事,这使我不确定。 这是一个干净的解决方案吗? 我认为这是一个普遍的问题,对于同一问题是否有更好的解决方案?

编辑

如果您对我的解决方案感兴趣,请在这里查看我的答案: https : //stackoverflow.com/a/30500985/395879

您是正确的,Spring MVC在这方面有点挑剔,这是一个普遍的问题。 但是有解决方法:

  • 将所有后备字段设置为字符串,并手动进行数字/日期等转换和空值检查。
  • 当字段不相关时,使用JavaScript将其设置为null。
  • 输入字段时,使用JavaScript验证字段。 这将解决您几乎所有的问题。

祝好运!

我知道这个问题很旧,但是我遇到了这个问题,正在寻找其他情况的答案。

我认为根据您的情况,您可以对表格使用继承,然后使用两种控制器方法:

表格如下所示:

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 ...
}

控制器方法如下所示:

@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
    }
}

注意, @RequestMapping注释包括一个params属性所以值isCompany参数确定哪个方法被调用。

还要注意,@ @Valid批注位于form参数上。

最后,在这种情况下,不需要任何组。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM