Skip to content

My custom validation annotation is not working in Spring Boot

i have created an annotation that has features such as checking if the entered string is null or at the assigned value.But the annotation doesn’t work. I don’t think it does any validation on the DTO.What am I doing wrong ? I also added the valid annotation on the controller. I don’t think the isValid() function works.

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;

import static java.lang.annotation.ElementType.PARAMETER;

@Documented
@Constraint(validatedBy = {SpecificStringValueValidator.class})
@Target( {PARAMETER} )
@Retention(RetentionPolicy.RUNTIME)
public @interface SpecificStringValue {
    //This annotation ensures input is not null and contains no empty strings
    //Also applies maximum minimum control if specified
    //Checks if the input is of length value given.
    int value() default 0;
    int min() default -9999;
    int max() default -9999;
    String message() default "Invalid String";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.Objects;

public class SpecificStringValueValidator implements ConstraintValidator<SpecificStringValue,String> {

    private SpecificStringValue specificValue;
    private boolean status = false;

    @Override
    public void initialize(SpecificStringValue specificValue) {
        ConstraintValidator.super.initialize(specificValue);
        this.specificValue = specificValue;
    }

    @Override
    public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
        String str = s;
        String noSpaceStr = str.replaceAll("\s", "");

        //This if block work if it is requested to have a certain length.
        if(specificValue.value() != 0){
            //Check does the string contain a space character?
            if(noSpaceStr.length() == s.length() && s.isEmpty() && s.length() == specificValue.value()){
                status = true;
            }
        }
        //If there is no specific value, it checks the max min.
        else {
            //Check does the string contain a space character?
            if(noSpaceStr.length() == s.length() && s.isEmpty() ){
               //Check the minimum number
                if(specificValue.min() != -9999){
                    if(s.length() >= specificValue.min()){
                        status = true;
                    }
                }
                //Check the maximum number
                if(specificValue.max() != -9999){
                    if(s.length() <= specificValue.max()){
                        status = true;
                    }
                }
            }
        }
        return status;
    }
}
public record CreateSellerRequestDTO(
@SpecificStringValue(value = 5,message = "Username cant be null") userName){}
@PostMapping
    public ResponseEntity<?> create(@RequestBody @Valid CreateSellerRequestDTO createSellerRequestDTO){
            sellerService.create(createSellerRequestDTO);
            return ResponseEntity.ok().build();
    }

Answer

Record classes are in fact auto-generated classes with immutable fields and a getter-style method for each field. How do you know where (on a method or a field) is the annotation @SpecificStringValue placed?

The target of the annotation is only PARAMETER so i suspect that the annotation is not propagated to the field (userName), which is what will trigger the validation. You should at least try to add METHOD and FIELD to the annotation targets