开发者

JSR-303: Yet Another Cross-field Validation Problem

开发者 https://www.devze.com 2023-02-01 03:48 出处:网络
I have a @Money constraint that indicates the annotated Double property is, well, money. I wrote a ConstraintValidator that checks if a @Money property has a valid value, which depends on a Currency i

I have a @Money constraint that indicates the annotated Double property is, well, money. I wrote a ConstraintValidator that checks if a @Money property has a valid value, which depends on a Currency instance. For example, USD has both dollar and cent values whereas Japanese Yen doesn't, so while 19.99 is a valid value for USD, it isn't for JPY. The Currency value is stored in another property of the same bean.

The problem is looking up the Currency property of a given bean within the ConstraintValidator. I thought about making it class-level validation, but it would be quite cumbersome and redundant to write at the class level which fields are money, and more importantly, you can only generate one error message, even if there is more than one money property that is invalid.

Any suggestions, even Hiberna开发者_运维知识库te Validator specific ones are welcome.

Thanks!


IMO, the simplest solution is to create a separate java class say Money that holds both information, the type of money (i.e. Currency) and the value of money.

public class Money {

    private Currency currency;
    private Double value;

    public Currency getCurrency() { return currency; }
    public void setCurrency(Currency currency) { this.currency = currency; }

    public Double getValue() { return value; }
    public void setValue(Double value) { this.value = value; }

    public boolean isValid() {
        if(getCurrency() == null || getValue() == null) {
            return false;
        }

        // critical logic goes here

        // sample code
        if("JPY".equalsIgnoreCase(currency.getCurrencyCode())) {
            int intValue = getValue().intValue();
            double diff = getValue() - intValue;
            if(diff > 0) {
                return false;
            }
        }

        /*double fractionValue = value - (value % (currency.getDefaultFractionDigits() * 10));
        if(fractionValue > currency.getDefaultFractionDigits() * 10) {
            return false;
        }*/

        return true;
    }

}

After this, create a constraint say @ValidMoney and MoneyValidator.

public class MoneyValidator implements ConstraintValidator<ValidMoney, Money> {

    @Override
    public void initialize(ValidMoney constraintAnnotation) {
        // TODO Auto-generated method stub
    }

    @Override
    public boolean isValid(Money value, ConstraintValidatorContext context) {
        return value.isValid();
    }

}

Example:-

public class Bid {
    @ValidMoney
    private Money bidAmount;    
}
0

精彩评论

暂无评论...
验证码 换一张
取 消