Как отобразить удобную для пользователя ошибку, когда 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)