我正在 IBM Worklight 平台上试验基于表单的身份验证,我目前正在学习位于此处的教程。
我有一些奇怪的行为,第一次尝试登录时它只会重新加载登录页面,但如果我第二次尝试使用完全相同的详细信息,它就可以工作。这种行为是一致的,我每次都能重现它。
仔细观察 JS 控制台,我可以看到正在打印:
openjpa-1.2.2-r422266:898935 nonfatal user error> org.apache.openjpa.persistence.InvalidStateException: The factory has been closed. The stack trace at which the factory was closed is available if Runtime=TRACE logging is enabled.
at org.apache.openjpa.kernel.AbstractBrokerFactory.assertOpen(AbstractBrokerFactory.java:673)
at org.apache.openjpa.kernel.AbstractBrokerFactory.newBroker(AbstractBrokerFactory.java:182)
at org.apache.openjpa.kernel.DelegatingBrokerFactory.newBroker(DelegatingBrokerFactory.java:142)
at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:192)
at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:145)
at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:56)
at sun.reflect.GeneratedMethodAccessor70.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean$ManagedEntityManagerFactoryInvocationHandler.invoke(AbstractEntityManagerFactoryBean.java:434)
at $Proxy36.createEntityManager(Unknown Source)
at org.springframework.orm.jpa.EntityManagerFactoryUtils.doGetTransactionalEntityManager(EntityManagerFactoryUtils.java:195)
at org.springframework.orm.jpa.EntityManagerFactoryUtils.getTransactionalEntityManager(EntityManagerFactoryUtils.java:142)
at org.springframework.orm.jpa.EntityManagerFactoryAccessor.getTransactionalEntityManager(EntityManagerFactoryAccessor.java:129)
at org.springframework.orm.jpa.JpaTemplate.execute(JpaTemplate.java:174)
at org.springframework.orm.jpa.JpaTemplate.executeFind(JpaTemplate.java:151)
at org.springframework.orm.jpa.JpaTemplate.findByNamedQuery(JpaTemplate.java:343)
at com.worklight.core.auth.impl.AuthenticationDAO.getAssociatedIdentities(AuthenticationDAO.java:93)
at com.worklight.core.auth.impl.AuthenticationContext$1.run(AuthenticationContext.java:513)
at com.worklight.core.auth.impl.AuthenticationContext$1.run(AuthenticationContext.java:492)
at com.worklight.core.util.RssBrokerUtils.doInTransaction(RssBrokerUtils.java:123)
at com.worklight.core.auth.impl.AuthenticationContext.saveAuthenticationResult(AuthenticationContext.java:492)
at com.worklight.core.auth.impl.AuthenticationContext.processRequest(AuthenticationContext.java:244)
at com.worklight.core.auth.impl.AuthenticationFilter.doFilter(AuthenticationFilter.java:99)
at org.eclipse.equinox.http.servlet.internal.FilterRegistration.doFilter(FilterRegistration.java:81)
at org.eclipse.equinox.http.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:35)
at com.worklight.gadgets.serving.filters.AuthenticityFilter.doFilter(AuthenticityFilter.java:74)
at org.eclipse.equinox.http.servlet.internal.FilterRegistration.doFilter(FilterRegistration.java:81)
at org.eclipse.equinox.http.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:35)
at com.worklight.gadgets.serving.filters.InstanceAuthenticationFilter.doFilter(InstanceAuthenticationFilter.java:65)
at org.eclipse.equinox.http.servlet.internal.FilterRegistration.doFilter(FilterRegistration.java:81)
at org.eclipse.equinox.http.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:35)
at org.eclipse.equinox.http.servlet.internal.ProxyServlet.processAlias(ProxyServlet.java:130)
at org.eclipse.equinox.http.servlet.internal.ProxyServlet.service(ProxyServlet.java:68)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
at org.eclipse.equinox.http.jetty.internal.HttpServerManager$InternalHttpServiceServlet.service(HttpServerManager.java:317)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:390)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:326)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:939)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:756)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)
搜索该堆栈跟踪揭示了一个先前的问题SO,据此建议某些东西正在调用close()
. EntityManagerFactory
我不确定这是在哪里/为什么会发生,因为所有这些都将在 Worklight 下进行管理。
这是我用于身份验证过程的 JS,在js/auth.js
var Authenticator = function() {
var LOGIN_PAGE_SECURITY_INDICATOR = 'j_security_check';
var USERNAME_INPUT_ID = '#usernameInputField';
var PASSWORD_INPUT_ID = '#passwordInputField';
var LOGIN_BUTTON_ID = '#loginButton';
function onFormSubmit() {
WL.Logger.debug("Entering auth.js.onFormSubmit()");
var reqURL = './' + LOGIN_PAGE_SECURITY_INDICATOR;
var params = {
j_username : $(USERNAME_INPUT_ID).val(),
j_password : $(PASSWORD_INPUT_ID).val()
};
onSubmitCallback(reqURL, {
parameters : params
});
}
return {
init : function() {
WL.Logger.debug("Inside auth.js.init");
$(LOGIN_BUTTON_ID).bind('click', onFormSubmit);
},
isLoginFormResponse : function(response) {
WL.Logger.debug("Inside auth.js.isLoginFormResponse " + response.responseText);
if (!response || response.responseText == null) {
WL.Logger.debug("Entering auth.js.isLoginFormResponse (), return false");
return false;
}
var indicatorIdx = response.responseText.search(LOGIN_PAGE_SECURITY_INDICATOR);
WL.Logger.debug("Entering auth.js.isLoginFormResponse (), return " + (indicatorIdx >= 0));
return (indicatorIdx >= 0);
},
onBeforeLogin : function(response, username, onSubmit, onCancel) {
WL.Logger.debug("Inside auth.js.onBeforeLogin");
onSubmitCallback = onSubmit;
onCancelCallback = onCancel;
if (typeof (username) != 'undefined' && username != null) {
$(USERNAME_INPUT_ID).val(username);
} else {
$(USERNAME_INPUT_ID).val('');
}
$(PASSWORD_INPUT_ID).val('');
},
onShowLogin : function() {
WL.Logger.debug("Inside auth.js.onShowLogin");
$.mobile.changePage("#loginPage");
},
onHideLogin : function() {
WL.Logger.debug("Inside auth.js.onHideLogin");
$.mobile.changePage("#page3");
}
};
}();
就像我提到的,第一次登录失败,它只是重新加载登录表单,我可以在 JS 控制台中看到上面的堆栈跟踪,但第二次它工作正常。我想知道第一次尝试时是否没有正确初始化某些东西,但第二次就可以了。谁能提出什么问题?
这些是我正在使用的页面元素:
<div data-role="page" id="page3">
<div data-theme="a" data-role="header">
<h3>Autenticated Page - Page3</h3>
</div>
<div data-role="content">
<h3>You are logged in -Page3</h3>
<a href="#page1">Go to page1</a>
</div>
<div data-theme="a" data-role="footer">
<input type="button" value="Logout"
onclick="WL.Client.logout('SampleAppRealm', {onSuccess: WL.Client.reloadApp});" />
</div>
</div>
<div data-role="page" id="loginPage">
<div data-theme="a" data-role="header">
<h3>Hello JQuery Mobile</h3>
</div>
<div data-role="content">
<div id="loginForm">
Username:<br/>
<input type="text" id="usernameInputField" autocorrect="off" autocapitalize="off" /><br />
Password:<br/>
<input type="password" id="passwordInputField" autocorrect="off" autocapitalize="off"/><br/>
<input type="button" id="loginButton" value="Login" />
</div>
</div>
<div data-theme="a" data-role="footer">
<h3>Copyright stuff</h3>
</div>
</div>