Как отобразить удобную для пользователя ошибку, когда Spring не может проверить java модели.утиль.Поле даты?

Я использую Spring 3.1.2.ОСВОБОЖДАТЬ. Я хочу отобразить сообщение об ошибке на моем 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));
...
}

я включил эти сообщения об ошибках в моих сообщениях.файл свойств (входит в контекст приложения 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>();

и вот сообщение об ошибке, которое я получаю при отправке моего форма с плохо отформатированной датой ...

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)

что еще мне нужно сделать / проверить, чтобы поймать плохо отформатированную дату? Я бы предпочел, чтобы отобразить сообщение об ошибке для пользователя, а не страницы gracelessly умирает.

вот метод контроллера, который должен обработать форму. Обратите внимание, что я уже включил 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);
}

6 ответов


посмотреть: Spring @Valid validator не вызывается должным образом (Roo, Hibernate).

короткий рассказ меняет подпись метода контроллера с

@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) 

исправлено все.


Я предполагаю, что вы должны связать форму в один из ваших POST методы с использованием @ModelAttribute. В том же методе bind a BindingResult bindingResult и все ошибки привязки должны быть захвачены в this bindingResult "объект". Внутри метода вы должны иметь возможность проверить

if (bindingResult.hasErrors()) {

и принять соответствующие меры.


Я считаю, что ошибка при форматирование данных. Чтобы подтвердить, что вам нужно отладить приложение и проверить значение даты. И другой хорошей практикой было бы полагать, что вы настраиваете стандартный формат для своего приложения.

следуйте приведенному ниже примеру:

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

аннотировать метод на этом классе контроллера с помощью этой аннотации уровня класса / метода:

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

больше info


`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/blog/spring/registering-propertyeditorss-with-spring-for-custom-objects-example.html


аргумент BindingResult должен быть рядом с проверяемой моделью. Например!--2-->

 public void checkout(
                         @Valid @ModelAttribute("legalContactDetails") LegalContactDetails legalContactDetails,
                         BindingResult legalContactDetailsResult,
                         @Valid @ModelAttribute("researchIntent") ResearchIntent researchIntent,
                         BindingResult researchIntentResult)