GWT中的会话管理

10

我正在使用GWT开发客户端应用程序。但是,我不确定如何处理会话管理。 GWT应用程序驻留在一个页面上,所有服务器调用都通过AJAX完成。如果服务器上的会话过期了。假设用户没有关闭浏览器,并且使用RPC向服务器发送一些请求,那么我的服务器如何通知应用程序会话已经过期,客户端部分应该再次显示登录屏幕?我的示例代码:

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()显示一些错误信息。
如何实现这个功能,需要在服务端和客户端都添加哪些代码?
3个回答

6

You could have the server throw an AuthenticationException to the client in case the user has been logged out.
This will be catched in the callbacks onFailure method, which then can redirect the user to the login-page.

Edit:
AuthenticationException is not a standard exception of course, i was just making an example. It might be best to stick with the standard exceptions.

To try if you caught an specific exception you could use the instanceof operator

    public void onFailure(Throwable e) {
                  if(e instanceof AuthenticationException) {
                        redirecttoLogin();
                  }
                  else {
                    showError(),
               }
            }


谢谢。您能否提供一些示例代码来检查是身份验证异常还是其他异常。与此同时,我会尝试搜索一下。 - DonX

1

这并不直接适用于使用RPC的人,但对于那些没有使用RPC的人,您应该从服务器发送HTTP 401。然后您可以在RequestBuilder回调中检查该状态码。


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中进行检查,并重定向到登录页面。

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);
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接