有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java JSR303验证组定义一个默认组

我有一个bean,它有许多字段用JSR-303验证注释注释。现在有一个新的要求,其中一个字段是强制性的,但仅在某些条件下

我环顾四周,找到了我需要的,验证组

这就是我现在拥有的:

public interface ValidatedOnCreationOnly {
}

@NotNull(groups = ValidatedOnCreationOnly.class)
private String employerId;
@Length(max = 255)
@NotNull
private String firstName;
@Length(max = 255)
@NotNull
private String lastName;

但是,当我在单元测试中运行此验证时:

@Test
public void testEmployerIdCanOnlyBeSetWhenCreating() {
    EmployeeDTO dto = new EmployeeDTO();

    ValidatorFactory vf = Validation.buildDefaultValidatorFactory();
    Set<ConstraintViolation<EmployeeDTO>> violations = vf.getValidator().validate(dto, EmployeeDTO.ValidatedOnCreationOnly.class);

    assertEquals(violations.size(), 3);
}

事实证明,所有非组注释的验证都被忽略,我只得到1个违规

我可以理解这种行为,但我想知道是否有一种方法可以使组也包括所有未注释的参数。如果不是的话,我就得这样做:

public interface AlwaysValidated {
}

public interface ValidatedOnCreationOnly extends AlwaysValidated {
}

@NotNull(groups = ValidatedOnCreationOnly.class)
private String employerId;
@Length(max = 255, groups = AlwaysValidated.class)
@NotNull(groups = AlwaysValidated.class)
private String firstName;
@Length(max = 255, groups = AlwaysValidated.class)
@NotNull(groups = AlwaysValidated.class)
private String lastName;

我正在使用的真正的类有更多的字段(大约20个),所以这个方法将一个明确的表示验证的方法变成了一团混乱

谁能告诉我有没有更好的办法?可能是这样的:

vf.getValidator().validate(dto, EmployeeDTO.ValidatedOnCreationOnly.class, NonGroupSpecific.class);

我在一个spring项目中使用它,所以如果spring有其他方法,我很高兴知道


共 (3) 个答案

  1. # 1 楼答案

    对我来说,添加默认值。到处上课不是好办法。 因此,我扩展了LocalValidatorFactoryBean,它使用一些组进行验证,并委托不使用任何组进行验证

    我用的是弹簧靴2.2.6。释放 我使用了SpringBootStarter验证依赖项

    我的bean用于验证

    public class SomeBean {
    
        @NotNull(groups = {UpdateContext.class})
        Long id;
        @NotNull
        String name;
        @NotNull
        String surName;
        String optional;
        @NotNull(groups = {CreateContext.class})
        String pesel;
        @Valid SomeBean someBean;
    }
    

    扩展LocalValidatorFactoryBean的自己的类的代码

    public class CustomValidatorFactoryBean extends LocalValidatorFactoryBean {
    
        @Override
        public void validate(Object target, Errors errors, Object... validationHints) {
            if (validationHints.length > 0) {
                super.validate(target, errors, validationHints);
            }
            super.validate(target, errors);
        }
    }
    
    

    通过@Bean或只使用@Component将其放到spring上下文中(如您所愿)

        @Bean
        @Primary
        public LocalValidatorFactoryBean customLocalValidatorFactoryBean() {
            return new CustomValidatorFactoryBean();
        }
    

    在某些RestController中使用它

    // So in this method will do walidation on validators with CreateContext group and without group
        @PostMapping("/create")
        void create(@RequestBody @Validated(CreateContext.class) SomeBean someBean) {
    
        }
    
        @PostMapping("/update")
        void update(@RequestBody @Validated(UpdateContext.class) SomeBean someBean) {
    
        }
    

    由于某些原因,调用DummyService时testValidation不起作用。RestController或其他Springbean提供的testValidation()。 仅在RestController端工作:/

    @Validated
    @Service
    @AllArgsConstructor
    class DummyService {
      public void testValidation(@NotNull String string, @Validated(UpdateContext.class) SomeBean someBean) {
            System.out.println(string);
            System.out.println(someBean);
        }
    }
    
  2. # 2 楼答案

    我只是想补充一下:

    如果您使用的是spring框架,那么可以使用org.springframework.validation.Validator

    @Autowired
    private Validator validator;
    

    要手动执行验证,请执行以下操作:

    validator.validate(myObject, ValidationErrorsToException.getInstance());
    

    在控制器中:

    @RequestMapping(method = RequestMethod.POST)
    public Callable<ResultObject> post(@RequestBody @Validated(MyObject.CustomGroup.class) MyObject request) {
        // logic
    }
    

    虽然以这种方式从javax.validation.groups.Default扩展将不起作用,但您必须在组中包含Default.class

    class MyObject {
    
        @NotNull(groups = {Default.class, CustomGroup.class})
        private String id;
    
        public interface CustomGroup extends Default {}
    }
    
  3. # 3 楼答案

    javax.validation.groups.Default中有一个Default组,它表示默认的Bean验证组。除非明确定义了组列表,否则:

    • 约束属于Default
    • 验证适用于Default

    您可以扩展此组:

    public interface ValidatedOnCreationOnly extends Default {}