当Spring无法验证模型的java.util.Date字段时,如何显示用户友好错误?

Dav*_*ave 8 validation error-handling spring model date

我正在使用Spring 3.1.2.RELEASE.如果我的日期字段格式不正确,我想在我的JSP上显示错误消息.我以为我会遵循所有正确的步骤.我在控制器中绑定了一个转换器......

@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));
...
}
Run Code Online (Sandbox Code Playgroud)

我在messages.properties文件中包含了这些错误消息(包含在Spring应用程序上下文中)

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
Run Code Online (Sandbox Code Playgroud)

这是我正在使用的模型:

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>();
Run Code Online (Sandbox Code Playgroud)

以下是我提交格式错误的日期时收到的错误消息...

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)
Run Code Online (Sandbox Code Playgroud)

我还需要做什么/检查以捕获格式错误的日期?我宁愿向用户显示友好的错误消息,而不是无理由地死亡的页面.

这是应该处理表单的控制器方法.注意我已经包含了一个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);
}
Run Code Online (Sandbox Code Playgroud)

Tej*_*eni 6

我假设您应该将表单绑定到您POST使用的方法之一@ModelAttribute.在同一方法中,绑定a BindingResult bindingResult和所有绑定错误都应该捕获到此bindingResult对象中.在方法内部,您应该能够检查

if (bindingResult.hasErrors()) {

并采取适当的行动.


Dav*_*ave 6

请参阅:Spring @Valid验证器未正确调用(Roo,Hibernate).

短篇小说正在改变控制器方法签名

@RequestMapping(value = "/save", method = RequestMethod.POST)
public ModelAndView save(final HttpServletRequest request,
                     final SampleUserForm sampleUserForm,
                     final Model model,
                     final BindingResult result)
Run Code Online (Sandbox Code Playgroud)

@RequestMapping(value = "/save", method = RequestMethod.POST)
public ModelAndView save(final HttpServletRequest request,
                         final Model model,
                         final SampleUserForm sampleUserForm,
                         final BindingResult result) 
Run Code Online (Sandbox Code Playgroud)

修复一切.