Sto usando Spring 3.1.2.RELEASE. Voglio visualizzare un messaggio di errore sul mio JSP se il mio campo data non è formattato correttamente. Pensavo di aver seguito tutti i passi giusti. Ho Binder un convertitore in mio controller ...Come posso visualizzare un errore user friendly quando Spring non è in grado di validare il campo java.util.Date di un modello?
@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));
...
}
Ho incluso questi messaggi di errore nel mio file messages.properties (inclusi nel contesto di applicazione della molla)
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
Qui è il modello che sto utilizzando:
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>();
E qui è il messaggio di errore che ricevo quando presento il mio modulo con una data di mal formattato ...
0.123.516,410617 millionsorg.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)
Cos'altro devo fare/controllare il trap per una data formattata male? Preferirei visualizzare un messaggio di errore amichevole all'utente piuttosto che la pagina che sta morendo senza grazia.
Ecco il metodo del controller che deve gestire il modulo. Avviso Ho già incluso un 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);
}
Viene visualizzato questo errore prima che venga richiamato il metodo POST del mio controller, in altre parole, non raggiunge mai lo stato in cui controllo BindingResult per gli errori. – Dave
L'aggiunta dei BindingResults come parametro successivo dopo quello annotato con @ModelAttribute nel metodo del controller risolve il problema, esattamente come Teja lo ha descritto. Senza i risultati vincolanti, la primavera lancia l'eccezione. Con i risultati vincolanti ti darà la possibilità di reagire ai problemi. –
Salve, BindingResult era già nel metodo del controller. Ho incluso la firma del metodo del controller nella domanda. Altri tipi di messaggi di errore vengono visualizzati correttamente, solo le conversioni di date stanno generando le eccezioni. – Dave