Java 游戏 2 - 您将如何从配置参数定义最大长度约束?

Java Play 2 - How would you define a maxlength constraint from config parameter?

使用 Play 2.3 (Java),我想使用 application.conf 中的参数作为约束的值。类似于:

public class Some {
    @Constraints.MaxLength(Play.application().configuration().getInt("some.text.maxlength", 1000))
    public String text;
}

但是我当然不能这样做,因为注解参数必须是常量。在 Java 中,绕过这个的方法是什么?我应该使用自定义验证器吗?或者还有其他选择吗?

感谢任何帮助。

正如您发现的,您不能通过注释使用它,但幸运的是,您可以编写自己的约束并读取其中的 application.conf,基于 MinLength 约束的快速示例:

文件: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 });
        }
    }
}

用法:

@utils.MyConstraints.SomeTextMinLength
public String text;

如你所见,要添加更多约束,你只需要将 MyFooConstraintMyFooConstraintValidator 对添加到 MyConstraints class 中,这样你也可以让它更通用:

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

}

然后像这样使用它:

@utils.MyConstraints.MinLengthByCfg(configKey = "some.text.maxlength", defaultValue = 3)
public String text;