基于操作的javax验证

时间:2017-06-12 05:13:12

标签: java spring validation

我正在尝试在DTO上使用javax验证。但是我希望根据使用此DTO的操作来应用这些验证。

假设我有以下DTO:

@Getter @Setter
public class CustomerDTO {

    @NotNull
    private String id;

    @NotNull 
    private String name;
}

我正在使用相同的DTO进行创建,更新和删除操作。 包含更新和删除操作我希望“id”为NotNull,但在Create中它必须为null。

但由于我使用相同的DTO,并且在控制器级别使用@Valid注释,因此它适用于所有属性。并且以下API失败,因为“id”不能为null

public CustomerDTO createCustomer(@Valid CustomerDTO customer, BindingResults results){
    if(results.hasErrors()){
        throw IllegalArgumentsException("Required params are mising");
    }
    customerService.create(customer);
}

2 个答案:

答案 0 :(得分:4)

由于您使用的是Spring,因此可以使用其@Validated注释和系统。

工作原理:每个验证注释都有一个字段groups。此字段允许您根据类确定何时应进行验证。你能做的是以下几点:

  1. 使用您需要的所有验证组创建一个ValidationGroups类。例如:
  2. import javax.validation.groups.Default;
    
    /**
     * Utility classes to distinct CRUD validations.<br>
     * <br>
     * Used with the
     * {@link org.springframework.validation.annotation.Validated @Validated}
     * Spring annotation.
     */
    public final class ValidationGroups {
    
        private ValidationGroups() {
        }
    
        // Standard groups
    
        public interface Create extends Default {};
        public interface Replace extends Default {};
        public interface Update extends Default {};
        public interface Delete extends Default {};
    }
    
    1. 对于您的情况,请注释您的id字段,如下所示:
    2. @Null(
          groups = Create.class
      )
      @NotNull(
          groups = { Update.class, Delete.class }
      )
      private String id;
      
      1. 最后,告诉控制器端您要使用@Validated注释而不是@Valid注释验证哪些组:
      2. public CustomerDTO createCustomer(@Validated(Create.class) CustomerDTO customer, BindingResult results) {
            if(results.hasErrors()){
                throw IllegalArgumentsException("Required params are mising");
            }
            customerService.create(customer);
        }
        
        // Etc. You can put multiple groups like @Validated({ Update.class, Delete.class })
        

        注意关于extends javax.validation.groups.Default中的ValidationGroups

        如果您未使用Create扩展javax.validation.groups.Default课程,则在不使用参数的情况下使用@Validated注释时,将无法执行验证规则。

        // @Validated without argument validate every annotation with the "Default" group
        public void test(@Validated MyForm form, BindingResult results) {
            // ...
        }
        

        您可以继承验证。例如,如果您希望Replace验证所有Create验证规则,请Replace继承Create

        public interface Create extends Default {};
        public interface Replace extends Create {};
        

答案 1 :(得分:0)

如果被调用的操作是“create”,则不要调用validate方法。或者,如果您必须验证DTO中的其他字段,请填写“id”的虚拟值,您可以在调用validate后忽略该值。