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.
Related
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.
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.
I have the following error
javax.validation.UnexpectedTypeException: HV000030: No validator could
be found for constraint 'javax.validation.constraints.Size' validating
type 'java.lang.Integer'. Check configuration for 'discounted'
My code is:
#Column(name= "discount_percentage")
#Size(min=0, max=90)
#Min(0)
#Max(90)
private Integer discountPercentage = 0;
I set it to 0 because i was getting a NullPointerException when loading my view.
And is Integer because i was reading in others question, and some people says that sometimes there are problems when using #Size with primitive types.
What should i do? Thanks in advance.
#Size is a Bean Validation annotation that validates that the associated String has a value whose length is bounded by the minimum and maximum values. And as your exception says it does not apply to Integer type.
Use: #Range
#Column(name= "discount_percentage")
#Range(min=0, max=90)
private Integer discountPercentage = 0;
Or you cloud also use only #Max or #Min and that will work too. For more info please take a look on this link.
#Size is not used to validate min/max.
It's used to validate size of collections, length of strings, etc.
In this case you should use #Min, #Max instead.
Refer here for complete document: https://docs.oracle.com/javaee/7/api/javax/validation/constraints/Size.html
I have observed this pattern when, the parameter type does not match with validator. as here List<String> is not matiching List<Long>
Ex Validator:
public class MaxValidation implements ConstraintValidator<MaxParameterSize, List<String>> {
....
}
Annotation Use :
public Response abc(#NotNull #MaxParameterSize(10) List<Long> parcelIds {
....
}
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)
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]*$)").