I am trying to validate a form using Spring with integrated JSR-303 validations with Hibernate implementation. I have a "confirm email" (emailConf) field that I would like to confirm is equal to the email field. I saw a post of someone doing it like this:
public class ContactInfoForm {
#NotEmpty
private String name;
#NotEmpty
#Email
private String email;
#Expression(value = "emailConf= email", applyIf = "emailConf is not blank")
private String emailConf;
...
}
However, this emailConf validation is not working (i.e. no error occurs when the fields don't match). I've seen a couple tutorials that have shown similar annotations, but can't find them anymore or any documentation on how this works. Does anyone know a way to validate "confirm email/password" fields through annotation? I am currently using the alternative, which is to implement Validator and validate the confirm fields in the validate method.
May you should have look at this question and its answers: there are many ways discussed how to do a such a validation (it is about password and password confirm, but the problem is the same).
What you need is a "Class-level constraint" (as described by JSR-303) if you want to compare 2 field of the same class. I don't think your #Expression will work that way.
Related
In my class, there's a field I want to validate, but I don't want to return it in the response. For that I've used the annotations
#Valid
#JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private User user;
The problem is that when I use WRITE_ONLY, the code doesn't check the validations. What can I do to fix that?
When you are using Spring-Boot, take a look at #Validated.
I have the same form that displays more or less fields depending on the user's role. So I use #JsonView to hide/ignore the fields that are not related to the current user's role. But the validation is still enabled and the #NotNull rule is triggered.
#JsonView({View.Admin.class, View.Tech.class})
#NotNull
private String name;
I would like to find a way to enable or disable some validation annotations for example when the user's role is not administrator.
Is it possible to use these view (View.Admin.class / View.Tech.class) as a group for validation please?
use #JsonIgnore may help you to achieve,because it will ignore the column and validation annotation as well
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.
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
I currently galley with data validation via Hibernate. Especially with the #Pattern annotation
Wholesale verification is always false, no matter what I do, so I can not save the object.
I try this, among other things:
#NotNull
#Size(max=30)
#SafeHtml
#Pattern(regexp="[a-zA-Z]", messsage="the name can only contain letters")
private String name;
et ceci :
#NotNull
#Size(max=30)
#SafeHtml
#Pattern(regexp="\\D", messsage="the name can only contain letters")
private String name;
In both case, if i write "toto," I have the error message that appears.
Someone an idea?
Have you tried [a-zA-Z]*
The patterns you have look like they only capture one letter. You need a * or a + to suggest multiple letters.