Spring 尝试登录时多次创建JSFbean

Spring 尝试登录时多次创建JSFbean,spring,jsf,view,primefaces,request,Spring,Jsf,View,Primefaces,Request,我正在尝试登录到我目前正在开发的网站,但我无法登录,因为登录bean被多次调用/创建,导致用户名和密码为空。我正在使用带有自定义登录页面的Spring,我试图将bean声明为请求和视图范围,但没有任何更改。当我尝试使用primefaces组件更改登录页面时,问题也出现了,但即使我以原始状态返回页面,我仍然存在此问题。我在Tomcat7上运行它 login.xhtml <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

我正在尝试登录到我目前正在开发的网站,但我无法登录,因为登录bean被多次调用/创建,导致用户名和密码为空。我正在使用带有自定义登录页面的Spring,我试图将bean声明为请求和视图范围,但没有任何更改。当我尝试使用primefaces组件更改登录页面时,问题也出现了,但即使我以原始状态返回页面,我仍然存在此问题。我在Tomcat7上运行它

login.xhtml

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core">
    <h:head>
    </h:head>
    <h:body>
        <div align="right" style="">
            <h:form id="loginFormId" prependId="false">
                <div id="loginFieldsPnlId">
                    <div id="loginFieldUsrContId">
                        <h:outputText id="outTxtUserNameId" value="Username:" ></h:outputText>
                        <h:inputText id="userName" required="true" value="#{loginMgmtBean.userName}" requiredMessage="Please enter username"></h:inputText>
                        <h:outputLabel id="outLblUserNameId" for="userName"></h:outputLabel>
                    </div>
                    <div id="loginFieldPassContId">
                        <h:outputText id="outTxtPasswordId" value="Password:"></h:outputText>
                        <h:inputSecret id="password"  required="true" value="#{loginMgmtBean.password}" requiredMessage="Please enter password"></h:inputSecret>
                        <h:outputLabel id="outLblPasswordId" for="password" ></h:outputLabel>
                    </div>
                    <div id="loginFieldPassContId">
                        <h:selectBooleanCheckbox id="rememberMe" value="#{loginMgmtBean.rememberMe}" label="Remember Me">Remember Me</h:selectBooleanCheckbox>
                    </div>
                </div>
                <div id="loginBtnPanelId">
                    <h:commandButton id="btnLoginId" value="Login" action="#{loginMgmtBean.login}" styleClass="loginPanelBtn"></h:commandButton>
                    <h:commandButton id="btnCancelId" value="Cancel" action="#{loginMgmtBean.cancel}" styleClass="loginPanelBtn" immediate="true" ></h:commandButton>
                </div>
            </h:form>
        </div>
        <div>
            <h:messages></h:messages>
        </div>
    </h:body>
</html>
applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:beans="http://www.springframework.org/schema/beans"
             xmlns:sec="http://www.springframework.org/schema/security"
             xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
                                 http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">

    <beans:bean id="navigator" name="navigator" class="extra.beans.Navigator" scope="session">
        <beans:property name="businessModel" ref="businessModel"></beans:property>
    </beans:bean>

    <beans:bean id="loginMgmtBean" name="loginMgmtBean" class="extra.beans.LoginBean" scope="prototype">
        <beans:property name="authenticationManager" ref="authenticationManager"></beans:property>
        <beans:property name="rememberMeServices" ref="rememberMeServices"></beans:property>
        <beans:property name="userDetailsService" ref="userDetailsService"></beans:property>
    </beans:bean>

    <beans:bean id="securityBean" class="extra.beans.SecurityHolderBean" scope="session">
    </beans:bean>

    <beans:bean id="businessModel" class="extra.business.model.BusinessModel" scope="prototype"></beans:bean>

    <beans:bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <beans:property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <beans:property name="url" value="jdbc:mysql://localhost:3306/extra" />
        <beans:property name="username" value="root" />
        <beans:property name="password" value="" />
    </beans:bean>

    <beans:bean id="userDetailsService" class="extra.dao.CustomJDBCDaoImpl">
        <beans:property name="dataSource" ref="dataSource"/>
        <beans:property name="enableAuthorities" value="false"/>
        <beans:property name="enableGroups" value="true"></beans:property>
        <beans:property name="usersByUsernameQuery">
            <beans:value>
                SELECT USERNAME, PASSWORD, ENABLED
                FROM USER
                WHERE USERNAME = ?
            </beans:value>
        </beans:property>
        <beans:property name="authoritiesByUsernameQuery">
            <beans:value>
                SELECT USERNAME, ROLE_NAME
                FROM ROLE
                WHERE USERNAME = ?
            </beans:value>
        </beans:property>
        <beans:property name="groupAuthoritiesByUsernameQuery">
            <beans:value>
                SELECT GROUP.ID, GROUP.NAME, AUTHORITY.AUTHORITY
                FROM `GROUP`, AUTHORITY, GROUP_MEMBER, `USER`
                WHERE `USER`.USERNAME = ? AND
                    GROUP_MEMBER.USER_ID = USER.ID AND
                    GROUP_MEMBER.GROUP_ID = GROUP.ID AND
                    AUTHORITY.GROUP_ID = GROUP.ID
            </beans:value>
        </beans:property>
    </beans:bean>

    <beans:bean id="rememberMeServices" class="org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices">
        <beans:property name="key" value="jsfspring-sec" />
        <beans:property  name="userDetailsService" ref="userDetailsService" />
        <beans:property  name="alwaysRemember" value="true" />
        <beans:property  name="tokenValiditySeconds" value="60" />
    </beans:bean>

    <beans:bean id="rememberMeAuthenticationProvider" class="org.springframework.security.authentication.RememberMeAuthenticationProvider">
        <beans:property name="key" value="jsfspring-sec"/>
    </beans:bean>

    <beans:bean id="rememberMeFilter" class="org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter">
        <beans:property name="rememberMeServices" ref="rememberMeServices"/>
        <beans:property name="authenticationManager" ref="authenticationManager" />
    </beans:bean>

    <beans:bean class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" id="passwordEncoder">
    </beans:bean>

    <beans:bean id="databasePasswordEncrypter" class="extra.dao.DBPasswordEncrypterBean" init-method="encryptDBPassword" depends-on="dataSource">
        <beans:property name="passwordEncoder" ref="passwordEncoder"></beans:property>
        <beans:property name="dataSource" ref="dataSource"></beans:property>
        <beans:property name="selectQuery">
            <beans:value>
                SELECT USERNAME, PASSWORD, ENCRYPTED
                FROM USER
                WHERE (ENCRYPTED = '' ||
                    ENCRYPTED IS NULL ||
                    ENCRYPTED = 'NO')
            </beans:value>
        </beans:property>
        <beans:property name="updateQuery">
            <beans:value>
                UPDATE USER
                SET PASSWORD = ?, ENCRYPTED='YES'
                WHERE USERNAME = ?
            </beans:value>
        </beans:property>
    </beans:bean>
</beans:beans>
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:sec="http://www.springframework.org/schema/security"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
                        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">

    <sec:http auto-config="true" use-expressions="true">
        <sec:intercept-url pattern="/pages/secure/**" access="hasRole('ROLE_USER')" />
        <sec:intercept-url pattern="/pages/unsecure/**" access="permitAll"/>
        <sec:intercept-url pattern="/pages/public/**" access="permitAll"/>
        <sec:intercept-url pattern="/**" access="permitAll"/>
        <sec:form-login login-page="/pages/public/login.jsf"/>
        <sec:remember-me key="jsfspring-sec" services-ref="rememberMeServices"/>
        <sec:logout invalidate-session="true" delete-cookies="JSESSIONID, REMEBER_ME_COOKIE" logout-success-url="/pages/public/login.jsf"/>
    </sec:http>

    <sec:authentication-manager alias="authenticationManager">
        <sec:authentication-provider ref="rememberMeAuthenticationProvider"></sec:authentication-provider>
        <sec:authentication-provider user-service-ref="userDetailsService">
            <sec:password-encoder ref="passwordEncoder">
            </sec:password-encoder>
        </sec:authentication-provider>
    </sec:authentication-manager>

    <sec:global-method-security pre-post-annotations="enabled"/>
</beans:beans>
securityContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:beans="http://www.springframework.org/schema/beans"
             xmlns:sec="http://www.springframework.org/schema/security"
             xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
                                 http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">

    <beans:bean id="navigator" name="navigator" class="extra.beans.Navigator" scope="session">
        <beans:property name="businessModel" ref="businessModel"></beans:property>
    </beans:bean>

    <beans:bean id="loginMgmtBean" name="loginMgmtBean" class="extra.beans.LoginBean" scope="prototype">
        <beans:property name="authenticationManager" ref="authenticationManager"></beans:property>
        <beans:property name="rememberMeServices" ref="rememberMeServices"></beans:property>
        <beans:property name="userDetailsService" ref="userDetailsService"></beans:property>
    </beans:bean>

    <beans:bean id="securityBean" class="extra.beans.SecurityHolderBean" scope="session">
    </beans:bean>

    <beans:bean id="businessModel" class="extra.business.model.BusinessModel" scope="prototype"></beans:bean>

    <beans:bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <beans:property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <beans:property name="url" value="jdbc:mysql://localhost:3306/extra" />
        <beans:property name="username" value="root" />
        <beans:property name="password" value="" />
    </beans:bean>

    <beans:bean id="userDetailsService" class="extra.dao.CustomJDBCDaoImpl">
        <beans:property name="dataSource" ref="dataSource"/>
        <beans:property name="enableAuthorities" value="false"/>
        <beans:property name="enableGroups" value="true"></beans:property>
        <beans:property name="usersByUsernameQuery">
            <beans:value>
                SELECT USERNAME, PASSWORD, ENABLED
                FROM USER
                WHERE USERNAME = ?
            </beans:value>
        </beans:property>
        <beans:property name="authoritiesByUsernameQuery">
            <beans:value>
                SELECT USERNAME, ROLE_NAME
                FROM ROLE
                WHERE USERNAME = ?
            </beans:value>
        </beans:property>
        <beans:property name="groupAuthoritiesByUsernameQuery">
            <beans:value>
                SELECT GROUP.ID, GROUP.NAME, AUTHORITY.AUTHORITY
                FROM `GROUP`, AUTHORITY, GROUP_MEMBER, `USER`
                WHERE `USER`.USERNAME = ? AND
                    GROUP_MEMBER.USER_ID = USER.ID AND
                    GROUP_MEMBER.GROUP_ID = GROUP.ID AND
                    AUTHORITY.GROUP_ID = GROUP.ID
            </beans:value>
        </beans:property>
    </beans:bean>

    <beans:bean id="rememberMeServices" class="org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices">
        <beans:property name="key" value="jsfspring-sec" />
        <beans:property  name="userDetailsService" ref="userDetailsService" />
        <beans:property  name="alwaysRemember" value="true" />
        <beans:property  name="tokenValiditySeconds" value="60" />
    </beans:bean>

    <beans:bean id="rememberMeAuthenticationProvider" class="org.springframework.security.authentication.RememberMeAuthenticationProvider">
        <beans:property name="key" value="jsfspring-sec"/>
    </beans:bean>

    <beans:bean id="rememberMeFilter" class="org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter">
        <beans:property name="rememberMeServices" ref="rememberMeServices"/>
        <beans:property name="authenticationManager" ref="authenticationManager" />
    </beans:bean>

    <beans:bean class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" id="passwordEncoder">
    </beans:bean>

    <beans:bean id="databasePasswordEncrypter" class="extra.dao.DBPasswordEncrypterBean" init-method="encryptDBPassword" depends-on="dataSource">
        <beans:property name="passwordEncoder" ref="passwordEncoder"></beans:property>
        <beans:property name="dataSource" ref="dataSource"></beans:property>
        <beans:property name="selectQuery">
            <beans:value>
                SELECT USERNAME, PASSWORD, ENCRYPTED
                FROM USER
                WHERE (ENCRYPTED = '' ||
                    ENCRYPTED IS NULL ||
                    ENCRYPTED = 'NO')
            </beans:value>
        </beans:property>
        <beans:property name="updateQuery">
            <beans:value>
                UPDATE USER
                SET PASSWORD = ?, ENCRYPTED='YES'
                WHERE USERNAME = ?
            </beans:value>
        </beans:property>
    </beans:bean>
</beans:beans>
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:sec="http://www.springframework.org/schema/security"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
                        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">

    <sec:http auto-config="true" use-expressions="true">
        <sec:intercept-url pattern="/pages/secure/**" access="hasRole('ROLE_USER')" />
        <sec:intercept-url pattern="/pages/unsecure/**" access="permitAll"/>
        <sec:intercept-url pattern="/pages/public/**" access="permitAll"/>
        <sec:intercept-url pattern="/**" access="permitAll"/>
        <sec:form-login login-page="/pages/public/login.jsf"/>
        <sec:remember-me key="jsfspring-sec" services-ref="rememberMeServices"/>
        <sec:logout invalidate-session="true" delete-cookies="JSESSIONID, REMEBER_ME_COOKIE" logout-success-url="/pages/public/login.jsf"/>
    </sec:http>

    <sec:authentication-manager alias="authenticationManager">
        <sec:authentication-provider ref="rememberMeAuthenticationProvider"></sec:authentication-provider>
        <sec:authentication-provider user-service-ref="userDetailsService">
            <sec:password-encoder ref="passwordEncoder">
            </sec:password-encoder>
        </sec:authentication-provider>
    </sec:authentication-manager>

    <sec:global-method-security pre-post-annotations="enabled"/>
</beans:beans>
web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    xsi:schemaLocation=
        "http://java.sun.com/xml/ns/javaee

http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"

    version="3.0">
    <!-- CONFIGURATION FILES both Bean definition and security -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/applicationContext.xml
            /WEB-INF/securityContext.xml
        </param-value>
    </context-param>
    <!-- CONFIGURATION FILES END HERE -->
    <!-- PROJECT STAGE START FOR DEVELOPEMENT MARK IT AS DEVELOPMENT, FOR TESTING, UAT, PRODUCTION REMOVE THIS -->
    <context-param>
        <param-name>javax.faces.PROJECT_STAGE</param-name>
        <param-value>Development</param-value>
    </context-param>
    <!-- PROJECT STAGE END -->
    <!-- Enable JSF Servlet -->
    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.jsf</url-pattern>
    </servlet-mapping>
    <!-- Enable JSF Server End-->
    <!-- Integrate JSF and Spring -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <!-- Integrate JSF and Spring End-->
    <!-- Enable Spring Filter, Spring Security works on the concept of Filters -->
    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>
            org.springframework.web.filter.DelegatingFilterProxy
        </filter-class>
    </filter>

    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <!-- Enable Spring Filter End -->
    <!-- Welcome File  -->
    <welcome-file-list>
        <welcome-file>/pages/common/index.jsp</welcome-file>
    </welcome-file-list>
    <!-- Welcome File End-->
</web-app>
faces-config.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<faces-config
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
    version="2.0">
    <!-- Enable Spring -->
    <application>
        <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
    </application>
    <navigation-rule>
        <display-name>pages/secure/secured.xhtml</display-name>
        <from-view-id>/pages/secure/secured.xhtml</from-view-id>
        <navigation-case>
            <from-action>#{loginMgmtBean.logout}</from-action>
            <from-outcome>loggedout</from-outcome>
            <to-view-id>/pages/public/login.xhtml</to-view-id>
            <redirect></redirect>
        </navigation-case>
    </navigation-rule>
    <navigation-rule>
        <display-name>pages/public/login.xhtml</display-name>
        <from-view-id>/pages/public/login.xhtml</from-view-id>
        <navigation-case>
            <from-action>#{loginMgmtBean.login}</from-action>
            <from-outcome>Secured</from-outcome>
            <to-view-id>/pages/secure/secured.xhtml</to-view-id>
        </navigation-case>
    </navigation-rule>
    <navigation-rule>
        <display-name>pages/secure/secured.xhtml</display-name>
        <from-view-id>/pages/secure/secured.xhtml</from-view-id>
        <navigation-case>
            <from-action>#{navigator.showAdminPersonalPage}</from-action>
            <from-outcome>adminPersonalDetails</from-outcome>
            <to-view-id>/pages/secure/adminPersonalDetails.xhtml</to-view-id>
            <redirect />
        </navigation-case>
    </navigation-rule>
</faces-config>

不要在spring上下文文件中定义bean。它应该由JSF而不是Spring来管理,为什么不呢?它以前是工作的,由spring管理。如果你这样做,@ViewScope就没用了。你在上面放了@ManagedBean,所以你希望它是一个JSF管理的bean,然后让它成为这样一个东西。@M.Deinum-你在说什么?OP正在将Spring业务对象注入他的@ViewScope中。这如何影响JSF托管bean的功能?@spyrosonserviam-nooooo的导航规则在哪里?如果您的逻辑导致nooo的结果,并且没有为其指定任何规则,那么NavigationHandler很可能会销毁bean并重新创建它以使您保持在同一页面上