Pregunta

Estoy utilizando dos anotaciones de validación en una propiedad en el grano:

@NotEmpty(message = "{name.required}")
@Pattern(regex = "^([A-Za-z0-9]{2,}(\\-[a-zA-Z0-9])?)$", message = "{invalid.name}")
private String name;

Si dejé el nombre vacío, tengo los dos errores pero quiero sólo el primer mensaje de error (Si la primera condición se produce mostrar su mensaje de error a continuación, omita la segunda condición).

¿Fue útil?

Solución

  

Si la primera condición se produce mostrar su mensaje de error a continuación, omita la segunda condición

Esto se puede hacer mediante la creación Compuesto restricción y anotar con limitación @ReportAsSingleViolation meta.

UserName.java

@ReportAsSingleViolation
@NotEmpty
@Pattern(regexp="^([A-Za-z0-9]{2,}(\\-[a-zA-Z0-9])?)$")
@Constraint(validatedBy = {})
public @interface UserName {
    String message() default "invalid userName!";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

Referencia 3.2. composición Constraint

Otros consejos

La respuesta aceptada no funciona como se espera. Composición restricción seguro que es buena sólo si desea a la lista TODO los errores en el TODO cadena de composición. No funciona si quieres abandono prematuro del primer error de validación.

Los documentos de ejemplo @ReportAsSingleViolation Los informes de errores de cada restricción composición individuo se ignoran .

Usando el ejemplo aceptar

@ReportAsSingleViolation
@NotEmpty
@Pattern(regexp="^([A-Za-z0-9]{2,}(\\-[a-zA-Z0-9])?)$")
@Constraint(validatedBy = {})
public @interface UserName {
    String message() default "invalid userName!";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

Esto significa que obtener el error de mensaje predeterminado de la anotación UserName que es "Nombre de usuario no válido!" incluso si falla @NotEmpty primera ....

Tengo que decir que estoy bastante sorprendida por lo mal este diseño es por los ejecutores de validación Java Bean. No tiene ningún sentido para haber compuesto validaciones si devuelve un mensaje completamente irrelevante. Se debe dejar primero y devolver el error correspondiente para la validación de que en realidad no !. De todos modos no hay manera de hacer esto sin cortes feos masivas. Tal simples giros tarea de validación en una pesadilla. 0_o

Mi trabajo en torno a la solución es hacer validaciones no compone, basta con crear 1 validación y poner en práctica todo usted mismo. No es seco, pero su simple por lo menos.

@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = PasswordValidator.class)
public @interface Password {
    String message() default "{com.example.Password.message}";

    Class<?>[] groups() default { };

    Class<? extends Payload>[] payload() default { };
}



public class PasswordValidator implements ConstraintValidator<Password, String> {
    private Pattern twoDigitsPattern;

    public void initialize(Password constraint) {
        twoDigitsPattern = Pattern.compile("(.*[\\d]){2}");
    }

    public boolean isValid(String password, ConstraintValidatorContext context) {
        context.disableDefaultConstraintViolation();

        if (password == null) {
            context.buildConstraintViolationWithTemplate("{javax.validation.constraints.NotNull.message}")
                    .addConstraintViolation();
            return false;
        }

        if (password.length() < 5 || password.length() > 10) {
            context.buildConstraintViolationWithTemplate("must be between 5 to 10 characters")
                    .addConstraintViolation();
            return false;
        }

        if (!twoDigitsPattern.matcher(password).matches()) {
            context.buildConstraintViolationWithTemplate("must contain 2 digits between [0-9]").addConstraintViolation();
            return false;
        }

        return true;
    }

}

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top