2015-08-07 4 views
0

Я уверен, что эта проблема ранее не описывалась. Я также уверен, что это глупая ошибка с моей стороны.Spring Validation: Null ModelAndView возвращен DispatcherServlet

Проблема вкратце:

  • Я создал форму входа пользователя.
  • Когда информация пользователей Логин является либо правильно или не на уровне услуг, все работает
  • Когда пользователь проверки входных данных не удается, я получаю следующее сообщение от весны: «Null ModelAndView вернулся в DispatcherServlet с именем „AssessmentAdmin“ : предполагается, что обработчик HandlerAdapter завершен запрос обработка «
  • Затем я получаю ошибку 400 на веб-странице:« Запрос, отправленный клиентом , был синтаксически неправильным ».

Мне кажется, что:

Когда Учётная правильно, модель не является нулевым. Я вижу это из журналов (см. Ниже). Когда пользовательский ввод не соответствует требованиям проверки, все вызовы AOP для проверки выполняются, но мой метод контроллера даже не вызывается (опять же, смотрите журналы).

JSPs:

Войти Форма:

<%@ page contentType="text/html; charset=UTF-8"%> 
 
<%@taglib uri="http://www.springframework.org/tags" prefix="spring"%> 
 
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%> 
 

 
<html> 
 
<head> 
 
<title><spring:message code="label.login" /></title> 
 
<style> 
 
.error { 
 
\t color: red; 
 
\t font-weight: bold; 
 
} 
 
</style> 
 
</head> 
 
<body> 
 

 

 

 
\t <h2 align="center"> 
 
\t \t <spring:message code="label.login" /> 
 
\t </h2> 
 
\t <h2 align="center"> 
 
\t \t <spring:message code="${loginError}" /> 
 
\t </h2> 
 
\t <form:form method="POST" action="/prototype2/xz/doXzLogin" commandName="userAdminForm"> 
 
\t \t <table> 
 
\t \t \t <tr> 
 
\t \t \t \t <td><form:label path="userName" > 
 
\t \t \t \t \t \t <spring:message code="label.name" /> 
 
\t \t \t \t \t \t <form:errors path="userName" cssClass="error"/> 
 
\t \t \t \t \t </form:label></td> 
 
\t \t \t \t <td><form:input path="userName" /></td> 
 
\t \t \t </tr> 
 
\t \t \t <tr> 
 
\t \t \t \t <td><form:label path="password"> 
 
\t \t \t \t \t \t <spring:message code="label.password" /> 
 
\t \t \t \t \t \t <form:errors path="password" cssClass="error"/> 
 
\t \t \t \t \t </form:label></td> 
 
\t \t \t \t <td><form:input path="password" /></td> 
 
\t \t \t </tr> 
 
\t \t \t <tr> 
 
\t \t \t \t <td><form:label path="pin"> 
 
\t \t \t \t \t \t <spring:message code="label.pin" /> 
 
\t \t \t \t \t \t <form:errors path="pin" cssClass="error"/> 
 
\t \t \t \t \t \t 
 
\t \t \t \t \t </form:label></td> 
 
\t \t \t \t <td><form:input path="pin" /></td> 
 
\t \t \t </tr> 
 
\t \t \t <tr> 
 
\t \t \t \t <td colspan="2"><input type="submit" value="Submit" /></td> 
 
\t \t \t </tr> 
 
\t \t </table> 
 
\t </form:form> 
 

 
</body> 
 
</html>

Войти Успех Форма (только тестовая страница сейчас)

<%@ page contentType="text/html; charset=UTF-8" %> 
 
<%@taglib uri="http://www.springframework.org/tags" prefix="spring"%> 
 
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%> 
 

 
<html> 
 
<head> 
 
<title><spring:message code="label.hello"/>: ${userName}</title> 
 
</head> 
 
<body> 
 

 

 
<h3 align="center"><spring:message code="label.hello"/>, ${userName}</h3> 
 
    
 
    <form:form method="POST" action="/prototype2/performXzLogin" commandName="userAdminForm"> 
 
    <table> 
 
    <tr> 
 
     <td><form:label path="userName"><spring:message code="label.name"/></form:label></td> 
 
     <td>${userName}</td> 
 
    </tr> 
 
    <tr> 
 
     <td><form:label path="password"><spring:message code="label.password"/></form:label></td> 
 
     <td>${password}</td> 
 
    </tr> 
 
    <tr> 
 
     <td><form:label path="pin"><spring:message code="label.pin"/></form:label></td> 
 
     <td>${pin}</td> 
 
    </tr> 
 
    
 
</table> 
 
</form:form> 
 
    
 
</body> 
 
</html>

Контроллер:

package com.prototype2.controller.user; 

    import javax.validation.Valid; 

    import org.springframework.beans.factory.annotation.Autowired; 
    import org.springframework.stereotype.Controller; 
    import org.springframework.ui.Model; 
    import org.springframework.validation.BindingResult; 
    import org.springframework.web.bind.annotation.ExceptionHandler; 
    import org.springframework.web.bind.annotation.RequestMapping; 
    import org.springframework.web.bind.annotation.RequestMethod; 

    import com.prototype2.controller.welcome.SS; 
    import com.prototype2.controller.welcome.SpringException; 
    import com.prototype2.model.user.UserAdmin; 
    import com.prototype2.service.user.AdminUserService; 
    import com.prototype2.service.user.BusinessService; 

    @Controller 
    public class UserControllerImpl 
    { 

    @Autowired 
    private AdminUserService auService; 

    @Autowired 
    private BusinessService businessService; 

    @RequestMapping(value = "/xzlogin", method = RequestMethod.GET) 
    public String xzLogin(Model model) 
    { 

    UserAdmin ua = new UserAdmin(); 
    model.addAttribute("userAdminForm", ua); 
    model.addAttribute("loginError", "label.blank"); 

    SS.getLogger().debug("xxx: xzLogin done"); 
    return "xzlogin"; 

    } 

    @RequestMapping(value = "/doXzLogin", method = RequestMethod.POST) 
    @ExceptionHandler(
    { SpringException.class }) 
    public String doXzLogin(@Valid UserAdmin u, Model model, BindingResult bindingResult) 
    { 

    SS.getLogger().debug("doXzLogin xxx UserAdmin: " + u.toString()); 
    SS.getLogger().debug("doXzLogin xxx Model size: " + model.toString()); 
    if (bindingResult.hasErrors()) 
    { 
    model.addAttribute("loginError", "label.loginfailed"); 
    return "xzlogin"; 
    } 
    SS.getLogger().debug("doing login: listing entries if any..."); 

    SS.getLogger().debug("User Logging In: " + u.getUserName()); 
    try 
    { 

    model.addAttribute("userAdminForm", u); 
    // model.addAttribute("userName", u.getUserName()); 

    // model.addAttribute("pin", u.getPin()); 

    // model.addAttribute("password", u.getPassword()); 

    if (auService.doAdminLogin(u)) 
    { 

     return "xzloginresult"; 
    } else 
    { 
     model.addAttribute("loginError", "label.loginfailed"); 

     return "xzlogin"; 

    } 
    } catch (Exception e) 
    { 
    SS.getLogger().error(e.getMessage(), e); 
    throw new SpringException(e.getMessage() + "Login Failed: Incorrect username, password, or pin"); 
    } 

    } 

    } 

ApplicationContext:

<beans xmlns="http://www.springframework.org/schema/beans" 
 
\t xmlns:context="http://www.springframework.org/schema/context" 
 
\t xmlns:mvc="http://www.springframework.org/schema/mvc" 
 
\t xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 
\t xmlns:tx="http://www.springframework.org/schema/tx" 
 
\t xsi:schemaLocation=" 
 
    http://www.springframework.org/schema/beans 
 
    http://www.springframework.org/schema/beans/spring-beans-3.2.xsd 
 
    http://www.springframework.org/schema/aop 
 
    http://www.springframework.org/schema/aop/spring-aop-3.2.xsd 
 
    http://www.springframework.org/schema/context 
 
    http://www.springframework.org/schema/context/spring-context-3.1.xsd 
 
    http://www.springframework.org/schema/tx 
 
    http://www.springframework.org/schema/tx/spring-tx-3.2.xsd 
 
    http://www.springframework.org/schema/mvc 
 
    http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd"> 
 

 
\t <!-- i18n --> 
 
\t <bean id="messageSource" 
 
\t \t class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> 
 
\t \t <property name="basename" value="classpath:messages" /> 
 
\t \t <property name="defaultEncoding" value="UTF-8" /> 
 
\t </bean> 
 

 
\t <bean id="localeChangeInterceptor" 
 
\t \t class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"> 
 
\t \t <property name="paramName" value="lang" /> 
 
\t </bean> 
 

 
\t <bean id="localeResolver" 
 
\t \t class="org.springframework.web.servlet.i18n.CookieLocaleResolver"> 
 
\t \t <property name="defaultLocale" value="en" /> 
 
\t </bean> 
 

 
\t <bean id="handlerMapping" 
 
\t \t class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"> 
 
\t \t <property name="interceptors"> 
 
\t \t \t <ref bean="localeChangeInterceptor" /> 
 
\t \t </property> 
 
\t </bean> 
 

 
\t <!-- Hibernate --> 
 
\t       ... 
 
\t 
 
\t <!-- validation --> 
 
\t <mvc:annotation-driven validator="validator" /> 
 
\t 
 
\t <bean id="validator" 
 
    class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/> 
 
</beans>

Журналы для успешного входа в систему (не ошибки, нет проблем. Модель не равно нулю):

>>******Controller Log: Successful login****** 





>> 
>> 
>>[DEBUG] "jake.app" 2015-08-07 11:47:00,731: Locale en 
>> 
>>[DEBUG] "jake.app" 2015-08-07 11:47:02,845: xxx: xzLogin done 
>> 
>>[DEBUG] "jake.app" 2015-08-07 11:47:14,305: doXzLogin xxx UserAdmin: UserAdmin [userName=jake0, password=1234, pin=1234, id=null] 
>> 
>>[DEBUG] "jake.app" 2015-08-07 11:47:14,306: doXzLogin xxx Model size: {userAdmin=UserAdmin [userName=jake0, password=1234, pin=1234, id=null], org.springframework.validation.BindingResult.userAdmin=org.springframework.validation.BeanPropertyBindingResult: 0 errors} 
>> 
>>[DEBUG] "jake.app" 2015-08-07 11:47:14,311: doing login: listing entries if any... 
>> 
>>[DEBUG] "jake.app" 2015-08-07 11:47:14,313: User Logging In: jake0 
>> 
>>[DEBUG] "jake.app" 2015-08-07 11:47:14,503: in ua service 
>> 
>>[DEBUG] "jake.app" 2015-08-07 11:47:14,504: logging in through dao :jake0 1234 1234 
>> 
>>[DEBUG] "jake.app" 2015-08-07 11:47:14,972: User Admin is UserAdmin [userName=jake0, password=1234, pin=1234, id=206] 
>> 
>>[DEBUG] "jake.app" 2015-08-07 11:47:14,974: User Admin is UserAdmin [userName=jake0, password=1234, pin=1234, id=206] 
>> 
>> 



******Root Log (i.e., Spring Log): Successful login****** 
>> 
>>[DEBUG] 2015-08-07 11:47:14,297: org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:861) DispatcherServlet with name 'AssessmentAdmin' processing POST request for [/prototype2/xz/doXzLogin] 
>> 
    (cut for sake of brevity) 
>> 
>>[DEBUG] 2015-08-07 11:47:15,002: org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1616) Invoking afterPropertiesSet() on bean with name 'xzloginresult' 
>> 
>>[DEBUG] 2015-08-07 11:47:15,003: org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:248) Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor' 
>> 
>>[DEBUG] 2015-08-07 11:47:15,004: org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1241) Rendering view [org.springframework.web.servlet.view.InternalResourceView: name 'xzloginresult'; URL [/WEB-INF/jsp/xzloginresult.jsp]] in DispatcherServlet with name 'AssessmentAdmin' 
>> 
>>[DEBUG] 2015-08-07 11:47:15,005: org.springframework.web.servlet.view.AbstractView.exposeModelAsRequestAttributes(AbstractView.java:432) Added model object 'userAdmin' of type [jake.prototype2.model.user.UserAdmin] to request in view with name 'xzloginresult' 
>> 
>>[DEBUG] 2015-08-07 11:47:15,006: org.springframework.web.servlet.view.AbstractView.exposeModelAsRequestAttributes(AbstractView.java:432) Added model object 'org.springframework.validation.BindingResult.userAdmin' of type [org.springframework.validation.BeanPropertyBindingResult] to request in view with name 'xzloginresult' 
>> 
>>[DEBUG] 2015-08-07 11:47:15,008: org.springframework.web.servlet.view.AbstractView.exposeModelAsRequestAttributes(AbstractView.java:432) Added model object 'userAdminForm' of type [jake.prototype2.model.user.UserAdmin] to request in view with name 'xzloginresult' 
>> 
>>[DEBUG] 2015-08-07 11:47:15,010: org.springframework.web.servlet.view.AbstractView.exposeModelAsRequestAttributes(AbstractView.java:432) Added model object 'org.springframework.validation.BindingResult.userAdminForm' of type [org.springframework.validation.BeanPropertyBindingResult] to request in view with name 'xzloginresult' 
>> 
>>[DEBUG] 2015-08-07 11:47:15,012: org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:166) Forwarding to resource [/WEB-INF/jsp/xzloginresult.jsp] in InternalResourceView 'xzloginresult' 
>> 
>>[DEBUG] 2015-08-07 11:47:15,046: org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:996) Successfully completed request 
>> 

Бревна для входа в систему с ошибкой проверки (модели равна нулю): **

>>******Controller Log: failed login****** 
>> 
>> 
>>[DEBUG] "jake.app" 2015-08-07 11:39:34,781: xxx: xzLogin done 
>> 
>> 
>> 
>> 
>> 


>>Root Log (i.e., Spring Log): failed login****** 
>> 
>> 
>> 
>>[DEBUG] 2015-08-07 11:39:42,741: org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:248) Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor' 
>> 
>>[DEBUG] 2015-08-07 11:39:42,742: org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:478) Finished creating instance of bean 'org.hibernate.validator.internal.constraintvalidators.NotNullValidator' 
>> 
>>[DEBUG] 2015-08-07 11:39:42,749: org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:450) Creating instance of bean 'org.hibernate.validator.internal.constraintvalidators.MinValidatorForNumber' 
>> 
>>[DEBUG] 2015-08-07 11:39:42,755: org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:248) Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor' 
>> 
>>[DEBUG] 2015-08-07 11:39:42,756: org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:478) Finished creating instance of bean 'org.hibernate.validator.internal.constraintvalidators.MinValidatorForNumber' 
>> 
>>[DEBUG] 2015-08-07 11:39:42,802: org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver.resolveException(AbstractHandlerExceptionResolver.java:134) Resolving exception from handler [public java.lang.String jake.prototype2.controller.user.UserControllerImpl.doXzLogin(jake.prototype2.model.user.UserAdmin,org.springframework.ui.Model,org.springframework.validation.BindingResult)]: org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors 
>>Field error in object 'userAdmin' on field 'pin': rejected value [0]; codes [Min.userAdmin.pin,Min.pin,Min.int,Min]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [userAdmin.pin,pin]; arguments []; default message [pin],1000]; default message [must be greater than or equal to 1000] 
>> 
>>[DEBUG] 2015-08-07 11:39:42,807: org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver.resolveException(AbstractHandlerExceptionResolver.java:134) Resolving exception from handler [public java.lang.String jake.prototype2.controller.user.UserControllerImpl.doXzLogin(jake.prototype2.model.user.UserAdmin,org.springframework.ui.Model,org.springframework.validation.BindingResult)]: org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors 
>>Field error in object 'userAdmin' on field 'pin': rejected value [0]; codes [Min.userAdmin.pin,Min.pin,Min.int,Min]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [userAdmin.pin,pin]; arguments []; default message [pin],1000]; default message [must be greater than or equal to 1000] 
>> 
>>[DEBUG] 2015-08-07 11:39:42,809: org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver.resolveException(AbstractHandlerExceptionResolver.java:134) Resolving exception from handler [public java.lang.String jake.prototype2.controller.user.UserControllerImpl.doXzLogin(jake.prototype2.model.user.UserAdmin,org.springframework.ui.Model,org.springframework.validation.BindingResult)]: org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors 
>>Field error in object 'userAdmin' on field 'pin': rejected value [0]; codes [Min.userAdmin.pin,Min.pin,Min.int,Min]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [userAdmin.pin,pin]; arguments []; default message [pin],1000]; default message [must be greater than or equal to 1000] 
>> 
>>[DEBUG] 2015-08-07 11:39:42,812: org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver.resolveException(AbstractHandlerExceptionResolver.java:134) Resolving exception from handler [public java.lang.String jake.prototype2.controller.user.UserControllerImpl.doXzLogin(jake.prototype2.model.user.UserAdmin,org.springframework.ui.Model,org.springframework.validation.BindingResult)]: org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors 
>>Field error in object 'userAdmin' on field 'pin': rejected value [0]; codes [Min.userAdmin.pin,Min.pin,Min.int,Min]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [userAdmin.pin,pin]; arguments []; default message [pin],1000]; default message [must be greater than or equal to 1000] 
>> 
>>[DEBUG] 2015-08-07 11:39:42,815: org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver.resolveException(AbstractHandlerExceptionResolver.java:134) Resolving exception from handler [public java.lang.String jake.prototype2.controller.user.UserControllerImpl.doXzLogin(jake.prototype2.model.user.UserAdmin,org.springframework.ui.Model,org.springframework.validation.BindingResult)]: org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors 
>>Field error in object 'userAdmin' on field 'pin': rejected value [0]; codes [Min.userAdmin.pin,Min.pin,Min.int,Min]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [userAdmin.pin,pin]; arguments []; default message [pin],1000]; default message [must be greater than or equal to 1000] 
>> 
>>[DEBUG] 2015-08-07 11:39:42,817: org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1034) Null ModelAndView returned to DispatcherServlet with name 'AssessmentAdmin': assuming HandlerAdapter completed request handling 
>> 
>>[DEBUG] 2015-08-07 11:39:42,818: org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:996) Successfully completed request 
>> 
>> 
>>******HTTP 400 message ****** 
>>The request sent by the client was syntactically incorrect. 
>> 
>> 
>> 
>> 
+0

@Mudassar, спасибо за внимание. Я не написал код транзакции, поскольку я полагаюсь на декларативные транзакции. Я что-то упускаю? – Jake

+0

Попробуйте удалить аргумент модели в методе постконтроллера, – Mudassar

+0

Также проверка отказа входа в систему должна быть частью вашей проверки и должна обрабатываться BindingResults – Mudassar

ответ

1

Проверка пароля должна быть частью проверки через BindingResult. Следовательно, здесь, в методе контроллера для сообщения, мы вручную добавляем ошибку JSR-303 к BindingResult.

if (bindingResult.hasErrors()){ 
     return "xzlogin"; 
    } 


model.addAttribute("userAdminForm", u); 

if (!auService.doAdminLogin(u)){ 
bindingResult.addError(new FieldError("userAdminForm","password","Invalid password ")); 
return "xzlogin"; 
       } 

Это позволяет Spring отображать их в виде через FieldError

+0

Дайте мне знать, если это решит вашу проблему. – Mudassar

+0

Определенно да! Бесконечно благодарен. – Jake

+0

Но, не занимая слишком много времени, вы можете объяснить, почему модель не была равна null, когда проверка прошла, но null, когда она не удалась? Также почему это привело к отказу даже вызвать метод контроллера doXzLogin. Я люблю АОП, но временами он очень непрозрачен – Jake

Смежные вопросы