JSR-303 validation groups define a default group

独自空忆成欢 提交于 2019-11-30 22:27:20

问题


I have a bean that has a lot of fields annotated with JSR-303 validation annotations. There is a new requirement now that one of the fields is mandatory, but only in certain conditions.

I looked around and have found what I needed, validation groups.

This is what I have now:

public interface ValidatedOnCreationOnly {
}

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

However, when I run this validation in a unit test:

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

It turns out that all of the non-group annotated validations are ignored and I get only 1 violation.

I can understand this behaviour but I would like to know if there is a way I can make the group include all non-annotated parameters as well. If not I'd have to do something like this:

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;

The real class I'm working with has a lot more fields (about 20), so this method turns what was a clear way of indicating the validations into a big mess.

Can anyone tell me if there is a better way? Maybe something like:

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

I'm using this in a spring project so if spring has another way I'll be glad to know.


回答1:


There is a Default group in javax.validation.groups.Default, which represents the default Bean Validation group. Unless a list of groups is explicitly defined:

  • constraints belong to the Default group
  • validation applies to the Default group

You could extends this group:

public interface ValidatedOnCreationOnly extends Default {}



回答2:


just wanted to add more:

if you're using spring framework you can use org.springframework.validation.Validator

@Autowired
private Validator validator;

and to perform validation manually:

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

and in controller:

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

although in this way extending from javax.validation.groups.Default won't work so you have to include Default.class in groups:

class MyObject {

    @NotNull(groups = {Default.class, CustomGroup.class})
    private String id;

    public interface CustomGroup extends Default {}
}


来源:https://stackoverflow.com/questions/35358447/jsr-303-validation-groups-define-a-default-group

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!