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

筅森魡賤 提交于 2020-01-01 19:34:10

问题


Using Play 2.3 (Java), I'd like to use a parameter from application.conf as a value for a constraint. Something like:

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

But of course I can't do this because the annotation parameter must be a constant. What would be the approach, in Java, to bypass this? Should I use a custom validator? Or is there another option?

Any help appreciated.


回答1:


As you discovered you can't use it via annotations, but fortunately you can write own constraints and read the application.conf within it, fast sample based on MinLength constraint:

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

usage:

@utils.MyConstraints.SomeTextMinLength
public String text;

As you can see to add more constraints like that you only need to add the pairs of MyFooConstraint and MyFooConstraintValidator into MyConstraints class, so you can also make it more generic:

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

}

and then use it like:

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


来源:https://stackoverflow.com/questions/29218835/java-play-2-how-would-you-define-a-maxlength-constraint-from-config-parameter

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