Yugandhar Gali
Yugandhar Gali

Reputation: 39

Java custom annotation on class as field (HAS-A relation)

Requirement - validate input as alpha numeric. I have two class are in Has-A relation

Quick help appreciate, thanks in advance.

public class Party {
    @InputContraint
    private String firstName;
    @InputContraint
    private String lastName;
    
    private Address address;
}

public class Address {
    @InputContraint
    private String countryCode;
    @InputContraint
    private String countryName;
}


@Documented
@Constraint(validatedBy = InputValidate.class)
@Target( { ElementType.METHOD, ElementType.FIELD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface InputContraint {
    String message() default "error.message";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

public class InputValidate implements ConstraintValidator<InputContraint, String> {
    @Override
    public boolean isValid(String inputVal, ConstraintValidatorContext context) {
        if (Utilities.isEmpty(inputVal))
            return true;
        //
        String regex = "^[a-zA-Z0-9]+$";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(inputVal);
        boolean valid = matcher.matches();
        return valid;
        }
}

Another way - still not working.
---
public class Address {
     @Pattern(regexp ="^[a-zA-Z0-9]+$")
     private String countryCode;
}
  1. I have created custom annotation and applied at field level

    • if field as String, it's working fine.
    • if filed as Class, is not working.
  2. Applied @Pattern(regex="^[a-zA-Z0-9]+$") at Address.countryCode

Upvotes: 0

Views: 1503

Answers (1)

silentsudo
silentsudo

Reputation: 6963

When you use @Valid it recurses to see if there any more valids are present and validates them all. I have also added getter methods for pojo classes, it doesn;t seems to work without getter methods. Below, I have just added how to use @Valid and did few adjustment in InputValidate. Please note that the import for @Valid comes from import javax.validation.Valid;

Your request body for successful validation should look like this:

{
    "firstName":"John",
    "lastName": "Doe",
    "address": {
        "countryCode":"01",
        "countryName":"United State"
    }
    
}

Controller implementation is as below:

@RestController
@RequestMapping("/")
class TestController {  

        @PostMapping("/party")
        public String valid(@Valid @RequestBody Party party) {
            return "all valid";
        }
}

You validation class is as below:

@Slf4j
public class InputValidate implements ConstraintValidator<InputContraint, String> {
    @Override
    public boolean isValid(String inputVal, ConstraintValidatorContext context) {
        if(inputVal != null) {
            String regex = "^[a-zA-Z0-9]+$";
            Pattern pattern = Pattern.compile(regex);
            Matcher matcher = pattern.matcher(inputVal);
            boolean valid = matcher.matches();
            log.info("InputValidate {} is {}", inputVal, valid);
            return valid;
        } else {
            return false;
        }
    }
}

party class

public class Address {
    @InputContraint
    private String countryCode;

    @InputContraint
    private String countryName;

    public String getCountryCode() {
        return countryCode;
    }

    public String getCountryName() {
        return countryName;
    }
}

Address class


public class Party {
    @InputContraint
    private String firstName;

    @InputContraint
    private String lastName;

    @Valid
    private Address address;

    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public Address getAddress() {
        return address;
    }
}

Reference:

https://www.sitepoint.com/java-bean-validation-object-graphs-valid-annotation/

Upvotes: 1

Related Questions