Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/341.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JSR-303/Spring MVC-使用组有条件地验证_Java_Spring Mvc_Bean Validation - Fatal编程技术网

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

Java JSR-303/Spring MVC-使用组有条件地验证,java,spring-mvc,bean-validation,Java,Spring Mvc,Bean Validation,我提出了一个使用JSR303组进行有条件验证的概念。“有条件地”意味着我有一些字段,这些字段只有在另一个字段具有特定值时才相关 示例:有一个选项可以选择是注册为个人还是公司。选择公司时,用户必须填写包含公司名称的字段 现在我想我用小组来做这个: class RegisterForm { public interface BasicCheck {} public interface UserCheck {} public interface CompanyCh

我提出了一个使用JSR303组进行有条件验证的概念。“有条件地”意味着我有一些字段,这些字段只有在另一个字段具有特定值时才相关

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

现在我想我用小组来做这个:

  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。例如,如果类型不兼容(预期int值,但用户用字母填写表单),则会在
结果中添加错误。这是一个问题,因为这些错误在JSP视图中通过
标记显示

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

由于我是Spring和JSR-303的新手,我想知道我是否完全走错了路。事实上,我必须自己实现一些事情,这让我感到不确定。这是一个干净的解决方案吗?对于同样的问题,有没有更好的解决方案,因为我认为这是一个常见的问题

编辑


如果您对我的解决方案感兴趣,请参阅我的答案:

您是正确的,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
    }
}
控制器方法如下所示:

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
注释位于
表单
参数上


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

您最终找到了合适的解决方案吗?我有一个类似的问题(),只有当用户向嵌套对象的任何字段输入值时,我才需要验证嵌套对象