spring mvc annotation validation integer - spring

I have an object.
public class MyObject
{
....
#Column(name = "a_number") #NotNull #NumberFormat(style = Style.NUMBER) #Min(1)
private Integer aNumber;
...
//getters and setters
}
In my controller I have #Valid annotation on my object being posted. I do have validation working on all my other fields in the class (their all Strings) except this number. If I enter a number from my form it works fine and if I violate the #Min(1) it also gives me the correct validation error. My problem however is that if you enter a string instead of a number it throw a NumberFormatException.
I've seen many examples of Integer and validation but no one accounts for if you enter a string into the form being posted. Do I need to do the validation else where? Javascript? I would like a solution that falls in line with the rest of spring validation so I could use this in other classes. I would just like an error stating it must be numeric. Also I tried using the #Pattern annotation but apparently thats just for strings.
Suggestions?

You can add the following to your file which controls your error messages (these are the generic ones it looks for in the case of a type mismatch:
typeMismatch.commandObjectName.aNumber=You have entered an invalid number for ...
typeMismatch.aNumber=You have entered an invalid number for ...
typeMismatch.java.lang.Integer=You have input a non-numeric value into a field expecting a number...
typeMismatch=You have entered incorrect data on this page. Please fix (Catches all not found)

For those who did not get the idea right here is what to do in spring 4.2.0.
Create a file name messages.properties in WEB-INF > classes folder. And put the above type mismatch messages in that file.
In spring configuration or servlet.xml file create the following bean.
<beans:bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<beans:property name="basename" value="messages"></beans:property>
</beans:bean>
And for your model attribute like private Integer aNumber; in the question along with other validation rules this rule is also applied for type mismatch conversion. You will get your desired message in this.
<form:errors path="aNumber"></form:errors>
Hope it helps others.

Still relevant, so I'll add the programmatical approach of message source bean definition:
#Bean
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("messages");
return messageSource;
}

Related

This annotation is not allowed at this location (#Valid)

I am trying to validate the list which is passed as a parameter to a controller in spring-boot application.
I referred Baeldung doc to perform the same, below is the code snippet which i tried to implement
#PostMapping
public void addAll(#RequestBody #NotEmpty(message = "Input movie list cannot be empty.") List<#Valid Movie> movies) {
movieService.addAll(movies);
}
but it throws an error saying "#Valid annotation is not allowed in this location" (this is compile time error, i haven't executed the code hence there is no stacktrace)
Suggest a fix for the same
I did the same thing as shown in the image
make sure the #Valid annotaion is in front of the List and not the generic list type.
Also make sure your Movie class implements #Valid validations.

javax regex validation of path variables in Spring

I have validation working for the beans and request parameters, however, my path variables fail to get validated:
#PathVariable #Pattern(regexp = "[A-Za-z0-9]+") String protocol
When I provide path var as ab!ab it doesn't fail the request with 400 status code but lets it pass with the value assigned to the argument.
I have also validated my regex online and it is valid and should be working fine.
Also, my rest controller does have #Validated annotation.
What am I missing here?
================UPDATE=============
I have tried other constraint annotations and none of them work, so it must something to do with the path variable validation. But what??
Make sure you have
hibernate-validator
dependency and add following bean:
#Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
return new MethodValidationPostProcessor();
}

Spring Boot JSR303 message code in annotation getting ignored

In my Spring Boot app I have a backing bean where I am using JSR303 validation. In the annotation, I have specified the message code:
#NotBlank(message = "{firstname.isnull}")
private String firstname;
Then in my message.properties I have specified:
firstname.isnull = Firstname cannot be empty or blank
My JavaConfig for the messageSource is:
#Bean(name = "messageSource")
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("messages");
messageSource.setDefaultEncoding("UTF-8");
return messageSource;
}
The validation works correctly but instead of seeing the actual string, I get the message code in my jsp page. In looking at the log file, I see an array of codes:
Field error in object 'newAccount' on field 'firstname': rejected value []; codes [NotBlank.newAccount.firstname,NotBlank.firstname,NotBlank.java.lang.String,NotBlank]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [newAccount.firstname,firstname]; arguments []; default message [firstname]]; default message [{firstname.isnull}]
If I change the my message code in the message.properties to one of the codes in the array, the string displays correctly in my web form. I didn't even have to change the code in the annotation. This indicates to me the code in the message parameter of the annotation is getting ignored.
I don't want to use the default code. I want to use my own. How can I make this work. Can you please provide a code example.
JSR303 interpolation normally works with ValidationMessages.properties file. However you can configure Spring to change that if you want (I was lazy to do so :)) e.g.
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<property name="validationMessageSource" ref="messageSource" />
</bean>
<mvc:annotation-driven validator="validator" />
According to JSR-303 specification message parameters are expected to be stored in ValidationMessages.properties files. But you can override the place where they are looked for.
So you have 2 options:
Move your messages to the ValidationMessages.properties file
Or override getValidator() method of your WebMvcConfigurerAdapter's descendant (JavaConfig in your case):
#Override
public Validator getValidator() {
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
validator.setValidationMessageSource(messageSource());
return validator;
}

Spring MVC + Hibernate validator : how can I override/internationalize the default error messages?

I'm working on a Spring MVC project in which I'm using Hibernate Validator to validate input fields from a form. As my project is Maven-based, I added this dependency:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator-annotation-processor</artifactId>
<version>4.1.0.Final</version>
</dependency>
The form validation process works fine but now, I would like to override or internationalize the default error messages.
For instance, by default, using the #NotEmpty annotation will yield the message "may not be empty". How I can replace this message by my own message? I've tried several solutions:
defining a Spring bean with id "messageSource" and setting its "basenames" property
creating ValidationMessages.properties file in the project classpath
But the default messages are still displayed...
Any hint?
Thx in advance.
Yes you can do that. You can load the error message from the properties files. But you need to have the key in a proper format. Like NotEmpty.ClassName.fieldName=fieldName Can not be empty.
You just need to specify your exact class name and property name in your properties files. Everything other is looking just perfect in your case.
You can also have a common error message for a particular type of validation annotation for all the fields having that annotation. Like javax.validation.constraints.NotNull=Notnull erro happened!
Hope this helps you. Cheers.
This is a bit explanation that how you can find the exact property name behind every annotation given or used for validation. See below mentioned steps.
#Size(min = 1, max = 50, message = "Email size should be between 1 and 50")
Now remove { message = "Email size should be between 1 and 50" } from validation tag.
After doing this your annotation will be like this.
#Size(min = 1, max = 50)
Now at controller side debug the method which is being called upon when submitting the form. Below is my method which is receiving the request when user hits submit.
public static ModelAndView processCustomerLoginRequest(IUserService userService,LoginForm loginForm,
HttpServletRequest request, HttpSession session, BindingResult result, String viewType, Map<String, LoginForm> model)
Now place a debug point at very first line of the method and debug the argument "result".
BindingResult result
While dubugging you will find a string like this in codes array.
Size.loginForm.loginId
Now define this string in your properties file and a message against that string. Compile and execute. That message will be displayed whenever that annotation wouldn't be validated.
Size.loginForm.loginId=email shouldn't be empty.
Basically spring makes its own string as key to its property file message. In above key
Size(#Size) = validation annotation name
loginForm = My Class Name
loginId = Property name in LoginForm class.
The Beauty of this method is it also runs fine while you will be using Spring Internationalization. It automatically switches the messages file as language changes.

spring validation with #valid where/how custom error messages

I'm trying to do some spring validation with the error messages in properties files.
But the examples I find all seem to have the values hardcoded, or gotten from a properties file but using a validator class and retrieving it there.
My setup is a bit different.
I'm using the #Valid annotation in my requestmapping, and my #Valid class uses #NotNull etc.
I've seen some examples where people do #NotNull(message = "blablabla");
But that's also hardcoded, and I'd like to put the messages in a properties file so I can easily edit it on the fly and so I can easily implement i18n in the future.
Any input on how to achieve this would be appreciated.
It works exactly the same way as with explicit Validator - you declare a MessageSource and write error messages in .properties files. Messages codes are formed as constraintName.modelAttributeName.propertyName:
publib class Foo {
#NotNull private String name;
...
}
.
#RequestMapping
public String submitFoo(#Valid Foo foo, ...) { ... }
messages.properties:
NotNull.foo.name=...
MessageSource declaration:
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value = "messages" />
</bean>

Resources