Java – Micronaut custom validation constraints, writing custom messages based on values

Micronaut custom validation constraints, writing custom messages based on values… here is a solution to the problem.

Micronaut custom validation constraints, writing custom messages based on values

Is there a way in Micronaut to define custom messages for validation in Micronaut.

Here is my code :

This is the annotation class:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Constraint(validatedBy = [])
@Documented
@interface CheckDecimal {
    String message() default "Invalid Decimal ({validatedValue})";

double minimum()

double maximum()

int integerLength()

int decimalLength()
}

This is my validation factory:

import io.micronaut.context.annotation.Factory
import io.micronaut.core.annotation.AnnotationValue
import io.micronaut.validation.validator.constraints.ConstraintValidator
import io.micronaut.validation.validator.constraints.ConstraintValidatorContext
import powehr.pandore.mn.validation.CheckDecimal

import javax.inject.Singleton

@Factory
class ValidatorFactory {

@Singleton
    ConstraintValidator<CheckDecimal, Double> checkDecimalValidator() {
        return { Double value,
                 AnnotationValue<CheckDecimal> annotation,
                 ConstraintValidatorContext context ->

final parameters = annotation.convertibleValues.asMap()
            final keySet = parameters.keySet()

if(value == null) {
                return true
            }

if(keySet.contains('minimum')) {
                double minimumValidator = parameters.get('minimum')
                if(value < minimumValidator) {
                     Define specific constraint message here
                    return false
                }
            }

if(keySet.contains('maximum')) {
                double maximumValidator = parameters.get('maximum')
                if(value > maximumValidator) {
                     Define specific constraint message here
                    return false
                }
            }

if(keySet.contains('integerLength')) {
                final integerLengthValidator = parameters.get('integerLength')
                final integerLength = value.toString().split(/\./)[0].length()

if(integerLength > integerLengthValidator) {
                     Define specific constraint message here
                    return false
                }
            }

if(keySet.contains('decimalLength')) {
                final decimalLengthValidator = parameters.get('decimalLength')
                final decimalLength = value.toString().split(/\./)[1].length()

if(decimalLength > decimalLengthValidator) {
                     Define specific constraint message here
                    return false
                }
            }

return true
        } as ConstraintValidator<CheckDecimal, Double>
    }
}

I use my constraint like this:

 @CheckDecimal(minimum = -1.0d, maximum = 97.0d, integerLength = 2, decimalLength = 4)

I want to be able to write specific messages for each violation of constraints. The context here doesn’t seem to offer many possibilities.

Is there a way to define specific message validation in checkDecimalValidator()?

Solution

No. The validation API modeled on this is designed to have each validation its own annotation.

Still, you should be able to use existing comments in all cases.

minimum = -1.0d is equivalent to @DecimalMin ("1.0"

).

maximum = 97.0d is equivalent to @DecimalMax("97.0"

).
integerLength = 2,

decimalLength = 4 is equivalent to @Digits (integer = 2, fraction = 4).

Related Problems and Solutions