I'm using Spring 3.1.2.RELEASE. I want to display an error message on my JSP if my date field isn't formatted properly. I thought I'd followed all the right steps. I binder a converter in my controller …
@InitBinder
public void initBinder(final WebDataBinder binder) {
final DateFormat dateFormat = new SimpleDateFormat(Contract.DATE_FORMAT);
dateFormat.setLenient(false);
// true passed to CustomDateEditor constructor means convert empty String to null
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
...
}
I have included these error messages in my messages.properties file (included in the Spring application context)
typeMismatch.activationDate=The activation date format should be of the form MM/dd/yyyy
typeMismatch.sampleUserForm.activationDate=The activation date format should be of the form MM/dd/yyyy
Here's the model I'm using:
public class SampleUserForm
{
private String userId;
private String firstName;
private String middleName;
private String lastName;
private String username;
private String url;
private String password;
private String confirmPassword;
private State state;
private java.util.Date activationDate;
private java.util.Date expirationDate;
private List<Product> products;
private Set<Role> roles = new HashSet<Role>();
And here is the error message I receive when I submit my form with a poorly-formatted date …
org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'sampleUserForm' on field 'activationDate': rejected value [1900]; codes [typeMismatch.sampleUserForm.activationDate,typeMismatch.activationDate,typeMismatch.java.util.Date,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [sampleUserForm.activationDate,activationDate]; arguments []; default message [activationDate]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.util.Date' for property 'activationDate'; nested exception is java.lang.IllegalArgumentException: Could not parse date: Unparseable date: "1900"]
org.springframework.web.method.annotation.ModelAttributeMethodProcessor.resolveArgument(ModelAttributeMethodProcessor.java:111)
org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:75)
org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:156)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:117)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:96)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789)
javax.servlet.http.HttpServlet.service(HttpServlet.java:754)
javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:183)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)
What else do I need to do/check to trap for a badly-formatted date? I would prefer to display a friendly error message to the user rather than the page gracelessly dying.
Here is the controller method that is supposed to handle the form. Notice I have already included a BindingResult.
@RequestMapping(value = "/save", method = RequestMethod.POST)
public ModelAndView save(final HttpServletRequest request,
final SampleUserForm sampleUserForm,
final Model model,
final BindingResult result)
{
String nextPage = "sampleusers/add";
m_sampleUserFormValidator.validate(sampleUserForm, result);
if (!result.hasErrors())
{
... process the model and determine the next page ...
} // if
return new ModelAndView(nextPage);
}
Exception HandlerThe @ExceptionHandler is an annotation used to handle the specific exceptions and sending the custom responses to the client. Define a class that extends the RuntimeException class. You can define the @ExceptionHandler method to handle the exceptions as shown.
The Validator interface works using an Errors object so that while validating, validators can report validation failures to the Errors object.
The most basic way of returning an error message from a REST API is to use the @ResponseStatus annotation. We can add the error message in the annotation's reason field. Although we can only return a generic error message, we can specify exception-specific error messages.
I assume you should be binding the form into one of your POST
methods using @ModelAttribute
. In the same method bind a BindingResult bindingResult
and all the binding errors should be captured into this bindingResult
object. Inside the method, you should be able to check for
if (bindingResult.hasErrors()) {
and take appropriate action.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With