Reputation: 3907
I am trying to create an object on Play 2.1 with decimal number variables. I want to set a validation using annotation, currently what I did is:
import play.data.validation.Constraints.Max;
import play.data.validation.Constraints.Min;
@Max(10)
@Min(0.1)
public Float someNumber;
but it said cannot convert double to long. How could I do this kind of validation?
Thank you
Upvotes: 0
Views: 1382
Reputation: 3907
This is what I did in the end...
@Target({FIELD})
@Retention(RUNTIME)
@Constraint(validatedBy = DoubleMinValidator.class)
@play.data.Form.Display(name="constraint.min", attributes={"value"})
public @interface DoubleMin {
String message() default DoubleMinValidator.message;
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
double value();
}
public class DoubleMinValidator extends Validator<Number> implements ConstraintValidator<DoubleMin, Number> {
final static public String message = "error.min";
private double min;
public DoubleMinValidator() {}
public DoubleMinValidator(double value) {
this.min = value;
}
public void initialize(DoubleMin constraintAnnotation) {
this.min = constraintAnnotation.value();
}
public boolean isValid(Number object) {
if(object == null) {
return true;
}
return object.doubleValue() >= min;
}
public Tuple<String, Object[]> getErrorMessageKey() {
return Tuple(message, new Object[] { min });
}
}
And call @DoubleMin(0.5) public Double num;
Do the same with Max.
Upvotes: 1
Reputation: 2065
You should create your own validator. Take a look at the Max
and Min
validation, that'll get you started on creating your own validator by extending AbstractAnnotationCheck
.
Here's what i did to be able to annotate attributes in JPA entities like @Decimal("15,2")
.
The interface to use as annotation:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Constraint(checkWith = DecimalCheck.class)
public @interface Decimal {
String[] value() default {""};
String[] lang() default {"*"};
}
And the DecimalCheck will look something like this:
public class DecimalCheck extends AbstractAnnotationCheck<Decimal> {
public int digits = 0;
public int decimals = 0;
@Override
public void configure(Decimal number) {
String[] values = StringUtils.split(number.value()[0], ",");
if (values.length > 1) {
decimals = Integer.parseInt(values[1]);
digits = Integer.parseInt(values[0]) - decimals;
}
}
public boolean isSatisfied(Object validatedObject, Object value, OValContext context, Validator validator) {
value = play.data.validation.Validation.willBeValidated(value);
if (value == null || value.toString().length() == 0) {
return true;
}
if (value instanceof BigDecimal) {
BigDecimal number = (BigDecimal) value;
int numberOfDecimals = number.scale();
int numberOfDigits = String.valueOf(number.intValue()).length();
if (numberOfDecimals <= decimals && numberOfDigits <= digits) {
return true;
}
}
return false;
}
}
You can of course extend the isSatisfied method to support more types for the value Object parameter. You might have a String
or a Long
or whatever you want to be able to use this check on. Or, in your case a Float
.
Upvotes: 1