33

I want to allow only positive integers for number fields including zero. How can I define this validation using JSR 303 ?
I tried

  1. @Min(value=0 message = "msg1") - But it allows float values like 1.2.

  2. @Digits(fraction = 0, integer = 10, message ="msg2") - It accepts negative values.

  3. @Min(value=0, message = "msg1" )
    @Digits(fraction = 0, integer = 10, message ="msg2") - It works fine but sometimes both the messages i.e. msg1 and msg2 are displayed.

Any suggestions?

Thanks!

Ajinkya
  • 22,324
  • 33
  • 110
  • 161

9 Answers9

61

Just use the annotation @Min in your bean:

@Min(value = 0L, message = "The value must be positive")
private Double value;
Ajinkya
  • 22,324
  • 33
  • 110
  • 161
Rodrigo Araujo
  • 1,062
  • 1
  • 9
  • 8
17

Looks like you are looking for natural numbers, I think you can use the regex pattern to get the desired output. Something like

@Pattern(regexp = "[\\s]*[0-9]*[1-9]+",message="msg")

Amit
  • 30,756
  • 6
  • 57
  • 88
jay
  • 791
  • 8
  • 20
9

You can use @Positive that works for the int and its wrappers too (ie Integer). This also will work for the BigInteger as well.

Arefe
  • 11,321
  • 18
  • 114
  • 168
  • `@Positive` considers 0 as an invalid value. https://javaee.github.io/javaee-spec/javadocs/javax/validation/constraints/Positive.html – Vijay Nandwana Jan 28 '22 at 11:12
  • 1
    You can use it with the @Min annotation and this can provide a solution. – Arefe Jan 28 '22 at 13:13
  • 5
    @VijayNandwana There is also `@PositiveOrZero`. https://javaee.github.io/javaee-spec/javadocs/javax/validation/constraints/PositiveOrZero.html – Namo Sep 18 '22 at 05:38
7

If you use hibernate-validator then you may create a custom constraint which combines @Min and @Digits from the 3rd option by using @ConstraintComposition(AND). When you add @ReportAsSingleViolation, only a custom message will be shown.

Slava Semushin
  • 14,904
  • 7
  • 53
  • 69
4

Its better to use range annotation like below for positive numbers

@Range(min = 0l, message = "Please select positive numbers Only")

For negative numbers

@Range(min = -9223372036854775808l, max = 0l, message = "Please select Negative numbers Only")
Nikhil Kumar K
  • 1,089
  • 10
  • 13
4

Another kind of solution and in my personal opinion cleaner and easier to read.

@Positive
@Digits(integer = 5, fraction = 0)
1

This is an example code from the answer https://stackoverflow.com/a/41675990/258544 above

@Documented
@Min(value=0, message = "add a min msg" )
@Digits(fraction = 0, integer = 10, message ="add a digit msg")
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {})
@ReportAsSingleViolation
public @interface NumberFormatValidator {

    String message() default "invalid number";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

}

It use Constraint composition http://docs.jboss.org/hibernate/validator/4.3/reference/en-US/html_single/#validator-customconstraints-compound and @ReportAsSingleViolation to avoid display both messages

0

Change the data time of your field from int to Integer and a message.properties file to set the message

Example: assuming your fieldName is myNumericField and belongs to a class called Test

  1. Change the datatype:

    • change private int myNumericField; to private Integer myNumericField;

    • Update getters and setters to use/return Integer

  2. Create custom message.properties file. This may appear to be more work but it's a more elegant and scalable solution rather than having the messages hardcoded in your annotations

    • Create a message.properties file under resources directory

    • Edit messages.properties and add the following line

    typeMismatch.Test.myNumericField=Please use integers only

    Remember to change Test and myNumericField for your class and field name

    • Edit your Application Context xml file and add the following tags before the <\beans> tag

    <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <property name="basenames" value="resources/messages" /> </bean>

Renzo Zagni
  • 121
  • 1
  • 5
0

Using the following combination solved the issue for me:

  @NotNull
  @Range(min = 1)
  @JsonProperty("end_range")
  private Integer endRange;

Make sure to use Integer class instead of int for @NotNull to work.

KayV
  • 12,987
  • 11
  • 98
  • 148