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;
如你所见,要添加更多约束,你只需要将 MyFooConstraint
和 MyFooConstraintValidator
对添加到 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;
使用 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;
如你所见,要添加更多约束,你只需要将 MyFooConstraint
和 MyFooConstraintValidator
对添加到 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;