Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java String validation using enum values and annotation

I want to validate a string against a set of values using annotations.

What I want is basically this:

@ValidateString(enumClass=com.co.enum) String dataType;  int maxValue; int minValue; int precision; 

or

@ValidateString(values={"String","Boolean", "Integer"}) String dataType;  int maxValue; int minValue; int precision; 


I also want to do some validation on other variables depending upon the value set in dataType:

if (dataType = "String") {     // maxValue, minValue, precision all should be null or zero } 


I can't think of a way to achieve this by custom annotations.
Somebody please help me.

like image 602
Joe Avatar asked Jun 09 '11 14:06

Joe


People also ask

How do you check if a string is present in an enum Java?

Then you can just do: values. contains("your string") which returns true or false.

How do you validate enums?

Validating That a String Matches a Value of an Enum For this, we can create an annotation that checks if the String is valid for a specific enum. This annotation can be added to a String field and we can pass any enum class.

Can we give string value in enum?

Since C# doesn't support enum with string value, in this blog post, we'll look at alternatives and examples that you can use in code to make your life easier. The most popular string enum alternatives are: Use a public static readonly string. Custom Enumeration Class.

Can we create custom annotation for validation?

In this way, we can create different custom annotations for validation purposes. You can find the full source code here. It is easy to create and use custom annotations in Java. Java developers will be relieved of redundant code by using custom annotations.


2 Answers

So here is the code being using Spring validation and works great for me. Full code is given below.


@EnumValidator annotation definition:

import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;  import javax.validation.Constraint; import javax.validation.Payload; import javax.validation.ReportAsSingleViolation; import javax.validation.constraints.NotNull;  @Documented @Constraint(validatedBy = EnumValidatorImpl.class) @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) @NotNull(message = "Value cannot be null") @ReportAsSingleViolation public @interface EnumValidator {    Class<? extends Enum<?>> enumClazz();    String message() default "Value is not valid";    Class<?>[] groups() default {};    Class<? extends Payload>[] payload() default {};  } 


Implementation of the above class:

import java.util.ArrayList; import java.util.List;  import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext;  public class EnumValidatorImpl implements ConstraintValidator<EnumValidator, String> {      List<String> valueList = null;      @Override     public boolean isValid(String value, ConstraintValidatorContext context) {         return valueList.contains(value.toUpperCase());     }      @Override     public void initialize(EnumValidator constraintAnnotation) {         valueList = new ArrayList<String>();         Class<? extends Enum<?>> enumClass = constraintAnnotation.enumClazz();          @SuppressWarnings("rawtypes")         Enum[] enumValArr = enumClass.getEnumConstants();          for (@SuppressWarnings("rawtypes") Enum enumVal : enumValArr) {             valueList.add(enumVal.toString().toUpperCase());         }     }  } 


Usage of the above annotation is very simple

 @JsonProperty("lead_id")  @EnumValidator(      enumClazz = DefaultEnum.class,      message = "This error is coming from the enum class",      groups = {Group1.class}  )  private String leadId; 
like image 86
Rajeev Singla Avatar answered Sep 23 '22 23:09

Rajeev Singla


This is what I did.

Annotation

public @interface ValidateString {      String[] acceptedValues();      String message() default "{uk.dds.ideskos.validator.ValidateString.message}";      Class<?>[] groups() default { };      Class<? extends Payload>[] payload() default { };  } 

Validation Class

public class StringValidator implements ConstraintValidator<ValidateString, String>{      private List<String> valueList;      @Override     public void initialize(ValidateString constraintAnnotation) {         valueList = new ArrayList<String>();         for(String val : constraintAnnotation.acceptedValues()) {             valueList.add(val.toUpperCase());         }     }      @Override     public boolean isValid(String value, ConstraintValidatorContext context) {         return valueList.contains(value.toUpperCase());     }  } 

And i used it like

@ValidateString(acceptedValues={"Integer", "String"}, message="Invalid dataType") String dataType;  Long maxValue; Long minValue; 

Now I need to figure out how to implement conditional check ie. if String then maxValue and minValue should be null or Zero..

Any ideas?

like image 36
Joe Avatar answered Sep 21 '22 23:09

Joe