JSF/Hibernate NotBlank validation - java

I have a simple JSF+RichFaces form with some fields and obviously a backing bean to store them. In that bean all the necessary properties have validation annotations (jsr303/hibernate), but I can't seem to find an annotation which would check if the property (String) is blank. I know there's a #NotBlank annotation in spring modules, but JSF doesn't support spring validation. Is there any easy way to check it or should I write my own annotation?
#Edit: I already tried #NotNull and #NotEmpty from jsr303 and hibernate, but they both failed I still can send a blank string like " ".

If you use Hibernate Validator 4.1 as your JSR-303 implementation, they provide a #NotBlank annotation that does EXACTLY what you're looking for, separate from #NotNull and #NotEmpty. You need to be using the (currently) latest version, but that will work.
If you can't go to the latest version for some reason, it doesn't take much to write an annotation yourself.

Hibernate Validator 4.1+ provides a custom string-only #NotBlank annotation that checks for not null and not empty after trimming the whitespace. The api doc for #NotBlank states:
The difference to NotEmpty is that trailing whitespaces are getting ignored.
If this isn't clear that #NotEmpty is trimming the String before the check, first see the description given in the 4.1 document under the table 'built-in constaints':
Check that the annotated string is not null and the trimmed length is greater than 0. The difference to #NotEmpty is that this constraint can only be applied on strings and that trailing whitespaces are ignored.
Then, browse the code and you'll see that #NotBlank is defined as:
#Documented
#Constraint(validatedBy=NotBlankValidator.class)
#Target(value={METHOD,FIELD,ANNOTATION_TYPE,CONSTRUCTOR,PARAMETER})
#Retention(value=RUNTIME)
#NotNull
public #interface NotBlank{
/* ommited */
}
There are two things to note in this definition. The first is that the definition of #NotBlank includes #NotNull, so it's an extension of #NotNull. The second is that it extends #NotNull by using an #Constraint with NotBlankValidator.class. This class has an isValid method which is:
public boolean isValid(CharSequence charSequence, ConstraintValidatorContext constraintValidatorContext) {
if ( charSequence == null ) { //this is curious
return true;
}
return charSequence.toString().trim().length() > 0; //dat trim
}
Interestingly, this method returns true if the string is null, but false if and only if the length of the trimmed string is 0. It's ok that it returns true if it's null because, as I mentioned, the #NotEmpty definition also requires #NotNull.

Perhaps #NotEmpty ?
Which is defined as:
#NotNull
#Size(min=1)
Since you are using richfaces, I guess you are using <rich:beanValidator />? It handles JSR 303 annotations.
Update: Try (taken from here):
#Pattern(regex="(?!^[\s]*$)").

Related

How to set #NotEmpty annotation messages in Spring?

In a Java (+ Spring Boot) project, there is a notation using javax.validation as shown below:
#NotEmpty(message = "validation.product.notEmpty")
private String product;
#NotEmpty(message = "validation.username.password")
private String password;
I have a look at the usage of them, but there are some points that I could not understand:
1. Is there a special usage e.g. conditional message displaying for validation.username.password? For example if username field is null, then display this message? Or is it completely the same manner as the product field?
2. I search the project, but could not find validation.product.notEmpty or validation.username.password. So, how do they work? I think there should be a definition for these messages, but as I did not find, is it come from default messages of javax.validation?
What is the difference between #EmailRegex and #Email? And is there
any need to also use #NotEmpty with these #EmailRegex or #Email
annotations?
#Email will not throw error for an empty String. So you need #NotEmpty to be sure that this String is not empty if you always require an email to be there.
#Email will consider valid everything that is in the form blabla#blabla.blabla. If you want to further constraint this you can use #EmailRegex so that you allow only blabla#blabla.eu by defining your own regular expression.
#EmailRegex does not seem to be included in hibernate annotations or spring annotations. So it is either a custom annotation imported from somewhere else or just a custom annotation of your application. Inspect the code to see how it actually behaves but from it's name I suppose it behaves as I have explained above.
I search the project, but could not find validation.product.notEmpty
or validation.username.password. So, how do they work? I think there
should be a definition for these messages, but as I did not find, is
it come from default messages of javax.validation?
It should be with {....} so like #NotEmpty(message = "{validation.username.password}") private String password;. In that case Spring will automatically read properties from the property files and apply the value for the property validation.username.password. If it does not exist then go to either application.properties or application.yaml and add that property.
Some more notes on this last one. I have seen some strange cases in backend-frontend applications which might be your case here.
#NotEmpty(message = "validation.username.password")
The actual message thrown here when the validation fails is validation.username.password. I have seen cases where the frontend then reads that message and binds a value to this one. I have seen this to be used when frontend supports multiple languages and binds another value for each language each time. This would explain why you don't have { } or such a property in your application.
#NotEmpty(message = "{validation.username.password}")
with an existing property validation.username.password= password can not be empty
will have as a result when the validation fails the message password can not be empty to be delivered.

Can Java Validator method validateProperty validate object with multiple fields inside?

As stated in the title, I'm using the Validator to validate fields based on their names like this:
mandatoryInputs.stream()
.map(x -> v.validateProperty(accountBenefitForm, x, AccountBenefitFormAdditionalInfo.class))
it works fine, but only for the simple fields like Strings that have their constraints in the accountBenefitForm for example:
#NotBlank(message = "Username can not be null.", groups = {AccountBenefitFormBasicInfo.class})
#Size(max = 255, message = "Username is too long (max size 255).")
private String username;
But it won't work for objects that have multiple fields inside them, like this one:
#Valid
private ContactData contactData;
where ContactData implementation looks like this:
#NotBlank(message = "You have to add e-mail address.", groups = {AccountBenefitFormAdditionalInfo.class})
#Email(message = "E-mail is not valid.", groups = {AccountBenefitFormAdditionalInfo.class})
#Size(max = 255, message = "E-mail is too long (max size 255).", groups = {AccountBenefitFormAdditionalInfo.class})
private String email;
#NotBlank(groups = {AccountBenefitFormAdditionalInfo.class})
private String phoneNumber;
Is there a way I can make this work or do I need to validate those more complex objects on their own?
You have basically two kinds of annotations that can be used for validations here: Spring annotations (#Validated) as well as the javax annotation (#Valid, #NotBlank) etc.
For Spring, you can luckily often skip the manual validation unless you have some custom constraints (e.g. if person lives in country ABC, they need to provide additional info). Annotating just the field is not enough if you don't cascade the validation from the outer class. This cascade can be done conveniently on method-level by annotating the method param with #Valid e.g.
void doSomething(#Valid ContactDataHolder contactDataHolder) { ... }
If you'd like to use validation in Spring, I would recommend to use the Spring Validator interface instead of the one from javax as it should give you the expected behavior for nesting. You might also decide to apply #Validated on the class level to save you from writing #Valid(ated) on the method level each time.
So I've managed to somewhat resolve my problem by using the Apache BVal. Heres the code to create a validator to use the validateProperty method with cascading validation enabled:
ValidatorFactory factory = Validation.byProvider(ApacheValidationProvider.class).configure().buildValidatorFactory();
CascadingPropertyValidator validator = factory.getValidator().unwrap(CascadingPropertyValidator.class);
validator.validateProperty(accountBenefitForm, x, true, Default.class, AccountBenefitFormAdditionalInfo.class))
where x is the string of field to validate, and if that field is annotated with #Valid, it will then validate the inside fields according to their own constraints.
Along the way I've also found out that you can just use the "normal" javax Validator and pass the field to validate as contactData.email which means validate email field of the contactData field of the object that u pass as first argument to the validateProperty method.
Edit:
BVal supports Bean Validation 1.1 (JSR 349) and not the 2.0 version(JSR 380), and since #NotBlank or #NotEmpty constrains are part of 2.0, it won't validate a field annotated with them. Here are the docs for the 1.1 , and 2.0

JSR Validation #Pattern allowing null values

When I annotate a field with #Pattern
#Pattern(regexp="someRegexp")
public String name;
If the JSON contains this field, with value as null, then I expect this regex to fail and thus invalid.
if the JSON does NOT contain this field, then it is fine for the validation to pass.
How to achieve this?
To Strings, I usually use #NotBlank for not empty strings, but im not sure at 100% that it doesnt allow null entries, but, in this case, use #NotNull annotation.
Edit: I was looking for an example and I got this from an old project:
#NotNull
#NotBlank
#Pattern(regexp = "somePattern")
public String getEmail() {
return this.email;
}
As you can see, I use NotNull and NotBlank even though I have a pattern there.

Dropwizard: make JSON integer parameter mandatory

I am developing a service using Dropwizard. In a POST request I receive a JSON and I want to throw an exception if the format of the request is not valid, in particular if some fields are missing. By default, as in the documentation, the Hibernate Validator is being used. This is the code:
public class ExtranetRequest {
#NotEmpty(message = "extranet_request_id should not be empty")
public String extranet_request_id;
#NotNull
public int hotel_id;
public List<ShopPattern> shop_patterns;
}
Everything works as expected for the field extranet_request_id (an exception is thrown if the field is not present in the JSON). However the request no error is raised if the field hotel_id is missing. I also tried the annotations #NotEmpty, #NotBlank, #Min(0), but none of them worked.
Did you try to make the hotel_id field an Integer?
An int cannot be null so it will be 0 by default which is OK for #NotNull or #Min(0) (it's checking that the number is higher or equal).
#NotEmpty or #NotBlank should make Hibernate Validator throw an exception though.

Do Javax and Hibernate Validations imply NotNull?

The list of supported Javax Validations are here.
The list of supported Hibernate Validations (extending Javax) are here.
Do each of these annotations "extend" or imply #NotNull?
For instance, if I annotate the following entity:
public class Widget {
#Email
private String email;
#URL
private String website;
// etc...
}
Does #Email and #URL also enforce #NotNull? Or are they simply applied/enforced if those properties are defined for a particular Widget instance?
Which annotations extend/imply #NotNull, and which ones don't? Are there any other implied relationships with these annotations?
No. If you look at the source code of EmailValidator from hibernate validator for example, it contains this code at the beginning of isValid() method:
if ( value == null || value.length() == 0 ) {
return true;
}
Same for URLValidator and so on. Generally all validators for the corresponding annotations consider the value valid when you try to validate null value, so a good rule of thumb would be to always perform the not-null validations separately.
Edit: here is a quote from JSR-303 specification related to this issue:
While not mandatory, it is considered a good practice to split the
core constraint validation from the not null constraint validation
(for example, an #Email constraint will return true on a null object,
i.e. will not take care of the #NotNull validation)

Categories

Resources