69

Is there are any java annotation(s) that can validate like the example below?

String test;
test = null; //valid
test = ""; //invalid
test = " "; //invalid
test = "Some values"; //valid
3
  • No, but you can write one of your own. :) Commented Jun 30, 2015 at 7:48
  • This would be some kind of assurance. This is, what mutator methods are for. I do not think that there is an annotation for this (at least not in plain Java). Commented Jun 30, 2015 at 7:48
  • 1
    any @Pattern(regexp = xxx) ??? Commented Jun 30, 2015 at 8:35

7 Answers 7

62

You need to create a custom annotation: @NullOrNotBlank

First create the custom annotation: NullOrNotBlank.java

@Target( {ElementType.FIELD})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = NullOrNotBlankValidator.class)
public @interface NullOrNotBlank {
    String message() default "{javax.validation.constraints.NullOrNotBlank.message}";
    Class<?>[] groups() default { };
    Class<? extends Payload>[] payload() default {};
}

Then the actual validator: NullOrNotBlankValidator.java

public class NullOrNotBlankValidator implements ConstraintValidator<NullOrNotBlank, String> {

    public void initialize(NullOrNotBlank parameters) {
        // Nothing to do here
    }

    public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) {
        return value == null || value.trim().length() > 0;
    }
}
Sign up to request clarification or add additional context in comments.

6 Comments

Just a quick one-liner for the validation: return str == null || str.trim().length() > 0;
@JeffersonLima I am not sure why my code is so verbose (I don't even like regex). Your one liner is spot on.
Great solution, I replaced the isValid check with: return value == null || !value.isBlank(); since I am using Java 11.
FYI, this is possible to do without a custom annotation using javax.validation.constraints.Size. I've added an answer for this.
@Phil unfortunately the Size annotation will count blank spaces, so cannot be used in this instance.
|
38

There isn't such an annotation in either javax.validation or Hibernate Validator. There was a request to add one to Hibernate Validator but it was closed as "won't fix" due to the possibility of writing your own relatively easily. The suggest solution was to either use your own annotation type defined like this:

@ConstraintComposition(OR)
@Null
@NotBlank
@ReportAsSingleViolation
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
@Retention(RUNTIME)
@Constraint(validatedBy = { })
public @interface NullOrNotBlank {
    String message() default "{org.hibernate.validator.constraints.NullOrNotBlank.message}";
    Class<?>[] groups() default { };
    Class<? extends Payload>[] payload() default { };
}

or to use the @Pattern annotation with a regular expression that requires a non-whitespace character to be present (as the Pattern annotation accepts nulls and does not match them against the pattern).

1 Comment

+1 for the @Pattern idea. This is great because many of the built-in annotations pass for null so that they don't conflict with @NotNull
11

This is possible without creating a custom annotation, by using javax.validation.constraints.Size

// Null values are considered valid
@Size(min=1) String test;

However as theprogrammer points out, blank strings such as " " are considered valid, which is not the case for @NotBlank.

4 Comments

such underrated solution +1
But it will break blank strings of length 1 like "_"(where _ means space)
This annotation is not applied for empty string, which is a string without any character "" . It works if you have a string with few characters, "abc" , but it doesn't work if you have an empty string "".
@user07 An annotation of Size(min=1) triggers a violation constraint when the size of the string is 0, which is the case for an empty string.
10

Where is a nice javax.validation.constraints.Pattern annotation.

You can annotate the field with:

@Pattern(regexp = "^(?!\\s*$).+", message = "must not be blank")

This checks if field matches regex. The regex itself is something but not blank (see details here). It uses negative lookahead.

1 Comment

This regex is valid but I tried using it and SonarQube flagged it as a security hotspot.
0

The best way is to create your own constraint validator,

//custom annotation
@Documented
@Constraint(validatedBy = CustomCheck.class)
@Target( { ElementType.METHOD, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomConstarint {
    String message() default "Invalid data";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
} 

//validation logic goes here
public class CustomCheck implements 
  ConstraintValidator<CustomConstarint, String> {
 
    @Override
    public void initialize(CustomConstarint customConstarint) {
    }
 
    @Override
    public boolean isValid(String field,
      ConstraintValidatorContext cxt) {
        //write your logic to validate the field
    }
}

1 Comment

0

For optional validations you could make use of jakarta.validation.constraints.AssertTrue, like

  @AssertTrue(message = "if not null, your value must not be empty or blank")
  private boolean isValueValid() {
    if (value != null) {
      return !value.trim().isEmpty();
    }
    return true;
  }

Comments

-7

Did you try Hibernate-Validator? I think that's what you are looking for.

import javax.validation.constraints.NotNull;

import org.hibernate.validator.constraints.NotBlank;
import org.hibernate.validator.constraints.NotEmpty;

public class MyModel  {

    @NotNull
    private String  str1;

    @NotEmpty
    private String  str2;

    @NotBlank
    private String  str3;

}

5 Comments

No, I don't think so, I want all those validation over my single variable
@NotBlank validates for all of your requirements on a single variable. I just added the others if you want less validation. E.g. if your variable may contain blank char then use @NotEmpty or if it may contain empty string then use @NotNull.
I just try to explain the details of related to your questions. Not all. What's wrong?
None of these matches the requirements in the question, which are that the value should not be empty but may still be null. All of these validation constraints fail on null.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.