8

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

@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));
...
}

我已将这些错误消息包含在我的 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

这是我正在使用的模型:

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>();

这是我在提交日期格式错误的表单时收到的错误消息……</p>

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)

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

这是应该处理表单的控制器方法。请注意,我已经包含了一个 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);
}
4

6 回答 6

6

See: Spring @Valid validator not invoked properly (Roo, Hibernate).

Short story is changing the controller method signature from

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

to

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

fixed everything.

于 2013-04-04T21:39:20.947 回答
6

我假设您应该将表单绑定到您的一种POST方法中,使用@ModelAttribute. 在同一个方法中绑定 aBindingResult bindingResult并且所有绑定错误都应该被捕获到这个bindingResult对象中。在方法内部,您应该能够检查

if (bindingResult.hasErrors()) {

并采取适当的行动。

于 2013-03-25T18:36:08.580 回答
1

我相信错误在于您格式化数据时。确认您需要调试您的应用程序并检查日期值。另一个好的做法是相信您为应用程序配置了标准格式。

请按照以下示例进行操作:

 @Configuration
 public class ApplicationContext {

    @Bean
    public FormattingConversionService conversionService() {

            // Use the DefaultFormattingConversionService but do not register
            // defaults
            DefaultFormattingConversionService conversionService = new DefaultFormattingConversionService(false);

            // Ensure @NumberFormat is still supported
            conversionService.addFormatterForFieldAnnotation(new NumberFormatAnnotationFormatterFactory());

            // Register date conversion with a specific global format
            DateFormatterRegistrar registrar = new DateFormatterRegistrar();
            registrar.setFormatter(new DateFormatter("dd/MM/yyyy")); // define your format
            registrar.registerFormatters(conversionService);

            return conversionService;
    }
  }
于 2013-04-03T17:16:57.247 回答
0

使用此类/方法级别注释对该控制器类上的方法进行注释:

@ExceptionHandler(BindException.class)
public String handleBindExcption(/*flexible parameters*/ ){
    //codes goes here
    return "view"; //view name or modelAndView 
}

更多信息

于 2013-03-30T02:54:06.073 回答
0

BindingResult 参数应位于正在验证的模型旁边。例如

 public void checkout(
                         @Valid @ModelAttribute("legalContactDetails") LegalContactDetails legalContactDetails,
                         BindingResult legalContactDetailsResult,
                         @Valid @ModelAttribute("researchIntent") ResearchIntent researchIntent,
                         BindingResult researchIntentResult)
于 2015-01-13T17:55:49.683 回答
0
`class DateBinderImpl` extends PropertyEditorSupport {



 public void setAsText(String text)
        throws IllegalArgumentException
    {
if(text.isEmpty()){

        Datelistener dateString = new Datelistener ();
        dateString.setValue("");
        setValue(dateString); setValue is method of PropertyEditorSupport
return;
    }
// for other date check condition use SimpleDateFormat class

public String getAsText()
    {
        Datelistener dateString = (Datelistener) getValue();
        if(dateString.getDate.isEmpty()){
            return "";

}


public class   Datelistener {
private String date;
public Datelistener ()
    {

    }
//setter and getter for date;

}

public class TestModel{
  private Datelistener date;
// gettter and setter for date




}
@InitBinder
 public void initBinder(WebDataBinder binder)
    {
        binder.registerCustomEditor(Datelistener, new DateBinderImpl());

    }

private boolean checkClientSideValidation(TestModel model, BindingResult bindingResult) {
Datelistener  dateobject=model.getDate(); // now you can obtained binded date value.
dateobject.getDate().isEmpty(){
 bindingResult.rejectValue("date;", "", new Object[] {""}, "");
            return true;
}

您可以查看此链接以获取更多信息 http://forum.springsource.org/showthread.php?58933-Handle-excpetions-from-custom-property-editor-spring-2-5 http://www.codercorp.com/博客/spring/registering-propertyeditorss-with-spring-for-custom-objects-example.html

于 2013-04-03T11:17:44.253 回答