我在客户端应用程序中使用GWT。但是,我不确定如何处理会话管理。 GWT应用程序驻留在一个页面上,所有服务器调用都通过AJAX完成。如果会话在服务器上过期。让我们假设用户没有关闭浏览器,并使用RPC向服务器发送一些请求,我的服务器如何通知应用程序会话已过期以及客户端部分应该再次显示登录屏幕?我的示例代码:< / p>
ContactDataServiceAsync contactDataService = GWT
.create(ContactDataService.class);
((ServiceDefTarget) contactDataService).setServiceEntryPoint(GWT
.getModuleBaseURL()
+ "contactDatas");
contactDataService.getContact(2,
new AsyncCallback<ContactData>() {
public void onFailure(Throwable caught) {
//code to show error if problem in connection or redirect to login page
}
public void onSuccess(ContactData result) {
displayContact(result);
}
});
如果会话过期,则只需要显示登录屏幕,否则它希望使用Window.alert()显示一些错误。
如何做到这一点以及服务器端和客户端所需的所有代码是什么?
答案 0 :(得分:6)
如果用户已经注销,您可以让服务器向客户端抛出AuthenticationException 这将在回调onFailure方法中捕获,然后该方法可以将用户重定向到登录页面。
编辑:
AuthenticationException当然不是标准的例外,我只是举个例子。最好坚持使用标准例外。
要尝试捕获特定异常,可以使用instanceof operator
public void onFailure(Throwable e) {
if(e instanceof AuthenticationException) {
redirecttoLogin();
}
else {
showError(),
}
}
答案 1 :(得分:1)
这不直接适用于那些使用RPC的人,但是对于那些不使用RPC的人,应该从服务器发送HTTP 401。然后,您可以在RequestBuilder回调中检查该状态代码。
答案 2 :(得分:0)
客户端:所有回调都会扩展一个抽象回调,您可以在其中实现onFailur()
public abstract class AbstrCallback<T> implements AsyncCallback<T> {
@Override
public void onFailure(Throwable caught) {
//SessionData Expired Redirect
if (caught.getMessage().equals("500 " + YourConfig.ERROR_MESSAGE_NOT_LOGGED_IN)) {
Window.Location.assign(ConfigStatic.LOGIN_PAGE);
}
// else{}: Other Error, if you want you could log it on the client
}
}
服务器:所有ServiceImplementations都扩展了AbstractServicesImpl,您可以访问SessionData。覆盖onBeforeRequestDeserialized(String serializedRequest)并检查那里的SessionData。如果SessionData已过期,则将空间错误消息写入客户端。此错误消息在您的AbstrCallback中获取checkt并重定向到登录页面。
public abstract class AbstractServicesImpl extends RemoteServiceServlet {
protected ServerSessionData sessionData;
@Override
protected void onBeforeRequestDeserialized(String serializedRequest) {
sessionData = getYourSessionDataHere()
if (this.sessionData == null){
// Write error to the client, just copy paste
this.getThreadLocalResponse().reset();
ServletContext servletContext = this.getServletContext();
HttpServletResponse response = this.getThreadLocalResponse();
try {
response.setContentType("text/plain");
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
try {
response.getOutputStream().write(
ConfigStatic.ERROR_MESSAGE_NOT_LOGGED_IN.getBytes("UTF-8"));
response.flushBuffer();
} catch (IllegalStateException e) {
// Handle the (unexpected) case where getWriter() was previously used
response.getWriter().write(YourConfig.ERROR_MESSAGE_NOT_LOGGED_IN);
response.flushBuffer();
}
} catch (IOException ex) {
servletContext.log(
"respondWithUnexpectedFailure failed while sending the previous failure to the client",
ex);
}
//Throw Exception to stop the execution of the Servlet
throw new NullPointerException();
}
}
}
另外,您还可以覆盖doUnexpectedFailure(Throwable t)以避免记录抛出的NullPointerException。
@Override
protected void doUnexpectedFailure(Throwable t) {
if (this.sessionData != null) {
super.doUnexpectedFailure(t);
}
}