代码之家  ›  专栏  ›  技术社区  ›  DonX

GWT中的会话管理

  •  10
  • DonX  · 技术社区  · 15 年前

    我正在为客户端应用程序使用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 回复  |  直到 12 年前
        1
  •  6
  •   Silfverstrom    15 年前

    您可以让服务器向客户机抛出一个authenticationException,以防用户已注销。
    这将在failure方法的回调中捕获,然后可以将用户重定向到登录页面。

    编辑:
    当然,authenticationException不是标准的例外,我只是举个例子。最好还是坚持标准例外。

    若要尝试捕获特定的异常,可以使用instanceof运算符

        public void onFailure(Throwable e) {
                      if(e instanceof AuthenticationException) {
                            redirecttoLogin();
                      }
                      else {
                        showError(),
                   }
                }
    
        2
  •  1
  •   JP Richardson    15 年前

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

        3
  •  0
  •   Hollerweger    12 年前

    客户: 所有回调都扩展一个抽象回调,在该回调中实现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
      }
    }
    

    服务器: 所有的服务实现都扩展了AbstractServiceSimpl,您可以在其中访问sessionData。重写OnBeforeRequestDeserialized(String SerializedRequest)并检查其中的sessionData。如果sessiondata已过期,则向客户端写入一条特殊错误消息。此错误消息正在AbstracCallback中获取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);
      }
    }