playframework - Java Play 2-¿Cómo definirías una restricción de longitud máxima desde el parámetro config?
playframework-2.0 constraints (1)
Como descubriste, no puedes usarlo a través de anotaciones, pero afortunadamente puedes escribir restricciones propias y leer la application.conf
dentro de ella, una muestra rápida basada en la restricción MinLength
:
archivo: app / utils / MyConstraints.java
package utils;
import play.Play;
import play.libs.F;
import javax.validation.Constraint;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.validation.Payload;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import static play.libs.F.Tuple;
public class MyConstraints {
public static abstract class Validator<T> {
public abstract boolean isValid(T object);
public boolean isValid(T object, ConstraintValidatorContext constraintContext) {
return isValid(object);
}
public abstract Tuple<String, Object[]> getErrorMessageKey();
}
@Target({FIELD})
@Retention(RUNTIME)
@Constraint(validatedBy = SomeTextMinLengthValidator.class)
@play.data.Form.Display(name="constraint.minLength")
public static @interface SomeTextMinLength {
String message() default SomeTextMinLengthValidator.message;
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
public static class SomeTextMinLengthValidator extends Validator<String> implements ConstraintValidator<SomeTextMinLength, String> {
final static public String message = "error.minLength";
private long min;
public SomeTextMinLengthValidator() {}
public SomeTextMinLengthValidator(long value) {
this.min = value;
}
public void initialize(SomeTextMinLength constraintAnnotation) {
this.min = Play.application().configuration().getInt("some.text.maxlength", 1000);
}
public boolean isValid(String object) {
if (object == null || object.length() == 0) {
return true;
}
return object.length() >= min;
}
public F.Tuple<String, Object[]> getErrorMessageKey() {
return Tuple(message, new Object[] { min });
}
}
}
uso:
@utils.MyConstraints.SomeTextMinLength
public String text;
Como puede ver para agregar más restricciones como esa, solo necesita agregar los pares de MyFooConstraint
y MyFooConstraintValidator
en la clase MyConstraints
, por lo que también puede hacerlo más genérico:
@Target({FIELD})
@Retention(RUNTIME)
@Constraint(validatedBy = MinLengthByCfgValidator.class)
@play.data.Form.Display(name="constraint.minLength", attributes={"configKey","defaultValue"})
public static @interface MinLengthByCfg {
String message() default MinLengthByCfgValidator.message;
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
String configKey();
long defaultValue();
}
public static class MinLengthByCfgValidator extends Validator<String> implements ConstraintValidator<MinLengthByCfg, String> {
final static public String message = "error.minLength";
private long min;
public MinLengthByCfgValidator() {}
public void initialize(MinLengthByCfg constraintAnnotation) {
this.min = Play.application().configuration().getLong(
constraintAnnotation.configKey(),
constraintAnnotation.defaultValue()
);
}
public boolean isValid(String object) {
if (object == null || object.length() == 0) {
return true;
}
return object.length() >= min;
}
public F.Tuple<String, Object[]> getErrorMessageKey() {
return Tuple(message, new Object[] {min});
}
}
y luego usarlo como:
@utils.MyConstraints.MinLengthByCfg(configKey = "some.text.maxlength", defaultValue = 3)
public String text;
Usando Play 2.3 (Java), me gustaría usar un parámetro de application.conf como un valor para una restricción. Algo como:
public class Some {
@Constraints.MaxLength(Play.application().configuration().getInt("some.text.maxlength", 1000))
public String text;
}
Pero, por supuesto, no puedo hacer esto porque el parámetro de anotación debe ser una constante. ¿Cuál sería el enfoque, en Java, para eludir esto? ¿Debo usar un validador personalizado? o hay otra opción?
Cualquier ayuda apreciada.