Validating dates on a form managed by Spring is a bit more tricky than checking a simple string attribute for emptiness.
You can use the org.springframework.format.annotation.DateTimeFormat
annotation on the field that you would like to validate. This annotation has an attribute called pattern
that allows you to set a the pattern to validate against. Example usage of the annotation:
public class PostForm { @DateTimeFormat(pattern = "yyyy-MM-dd") @NotNull(message = "Please provide a date.") private Date date; private String contents; // getters and setters... }
So far it was similar to using other validation annotations. However, you might notice that this annotation does not have a message
attribute, so you can’t specify what message should be printed. Let’s see what error message we get back if we use the annotation. I used 2014-99-11
as the date and yyyy-MM-dd
as the pattern to validate against.
Failed to convert property value of type java.lang.String to required type java.util.Date for property date; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type java.lang.String to type @org.springframework.format.annotation.DateTimeFormat @javax.validation.constraints.NotNull java.util.Date for value 2014-99-11; nested exception is java.lang.IllegalArgumentException: Unable to parse 2014-99-11
You can see that this results in not too nicely looking error message that explains what is the problem in detail…but users may expect a bit more concise message.
To override the default message, you need to have a messageSource and in that a message with a specific key that corresponds to the validated attribute.
Our message source is set up like this in the application context:
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> <property name="basenames"> <value>classpath:i18n/messages</value> </property> </bean>
Of course we have a messages.properties
file in the i18n
folder under our classpath. Our messages.properties
file looks like this:
typeMismatch.postForm.date=Please enter a valid date.
The name of the message key is very important. It is structured like this: {ValidationClass}.{modelObjectName}.{field}
. You don’t necessarily need to specify the whole key, because the resolving happens in the following way in our case:
- First the
typeMismatch.postForm.date
key is looked up. - If it is not found, the
typeMismatch.postForm
key is looked up. - If it is not found, the
typeMismatch
key is looked up. - If it is not found, the default message will be rendered.
Download
You can download the source code of an example application here.