Issue
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();
}
Solution
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
Answered By - Michail Alexakis
Answer Checked By - Robin (JavaFixing Admin)