GWT Java - 如何关闭窗口(注销)

时间:2016-03-02 03:15:19

标签: javascript java gwt

我已经读过要退出应用程序需要关闭窗口,我找到了这段代码:

这个答案有你想要的: How to run JavaScript function from GWT Java with JSNI?

特别是在Java中:

myButton.addClickHandler(new ClickHandler(){
public void onClick(ClickEvent event) {
closeWindow();
};
});

public static native void closeWindow() /*-{ $wnd.closeWindow();}-*/;

然后在您应用的.html页面中使用JavaScript:

<script type="text/javascript" language="javascript">
function closeWindow() {
window.open('','_self','');
window.close();
}</script>

我已在我的应用程序中实现了这个:

    //Log Out Button
    Button logOutButton = new Button("Log Out");
    logOutButton.addClickHandler(new ClickHandler(){
        public void onClick(ClickEvent event) {
        closeWindow();
        }
    });

    public static native void closeWindow() /*-{ $wnd.closeWindow();}-*/;

HTML:

<!doctype html>
<html>
    <head>
        <meta http-equiv="content-type" content="text/html; charset=UTF-8">

        <!--                                                               -->
        <!-- Consider inlining CSS to reduce the number of requested files -->
        <!--                                                               -->
        <!-- <link type="text/css" rel="stylesheet" href="org.AwardTracker.AwardTracker.AwardTracker.css"> -->

        <!--                                           -->
        <!-- Any title is fine                         -->
        <!--                                           -->
        <title>Wrapper HTML for AwardTracker</title>

        <!--                                           -->
        <!-- This script loads your compiled module.   -->
        <!-- If you add any GWT meta tags, they must   -->
        <!-- be added before this line.                -->
        <!--                                           -->
        <!-- script language="javascript" src="org.AwardTracker.AwardTracker/org.AwardTracker.AwardTracker.nocache.js" --><!-- /script -->
        <script src="org.AwardTracker.AwardTracker/org.AwardTracker.AwardTracker.nocache.js">
            <type="text/javascript">
            function closeWindow() {
                window.open('','_self','');
                window.close();
            }
        </script>

    </head>

    <!--                                           -->
    <!-- The body can have arbitrary html, or      -->
    <!-- we leave the body empty because we want   -->
    <!-- to create a completely dynamic ui         -->
    <!--                                           -->
    <body>

        <!-- OPTIONAL: include this if you want history support -->
        <iframe id="__gwt_historyFrame" style="width:0;height:0;border:0"></iframe>

    </body>

</html>

但是,我在行上收到以下错误:

closeWindow(); 

&#34;对于new ClickHandler(){}&#34;

类型,未定义closeWindow()方法
public static native void closeWindow() /*-{ $wnd.closeWindow();}-*/;

此行有多个标记      - 语法错误,插入&#34; EnumBody&#34;完成BlockStatement      - 令牌上的语法错误&#34; void&#34;,@ expected      - 语法错误,插入&#34;枚举标识符&#34;去完成      EnumHeaderName

感谢所有回复的人。根据您的回复...... 我在我的应用程序中使用类似(通过RemoteServiceServlet)的会话。因此,如下面的响应,我需要先使会话无效,然后从dom中删除元素。所以尝试了以下内容:

在客户端:

        logOutButton.addClickHandler(new ClickHandler(){
            public void onClick(ClickEvent event) {
            //Invalidate the session and then reload the application.
            AsyncCallback<Void> callback = new InvalidateSessionHandler<Void>(SelectPersonView.this);
            rpc.invalidateSession(callback);
            }
        });

class InvalidateSessionHandler<T> implements AsyncCallback<Void> {
    SelectPersonView view;

    public InvalidateSessionHandler(SelectPersonView view) {
        this.view = view;
    }

    public void onFailure(Throwable ex) {
        System.out.println("RPC call failed - InvalidateSessionHandler - Notify Administrator.");
        Window.alert("Connection failed - please retry.");
    }

    public void onSuccess(Void result) {
        //Reload the application.
        Window.Location.assign("/");    
    }
}

在服务器端:

public void invalidateSession() {
    getThreadLocalRequest().getSession().invalidate(); // kill session 
}

这似乎有效。但是,我在本地测试多个会话时遇到问题,而且我没有可以部署的测试服务器。因此,我可以请一位知道他们在这个空间做什么的人检查它,以确保我不会将问题引入生产。我最担心的是,这将使所有人都退出。我特别特别,因为我的情况是会话没有划分,用户可以看到其他人的数据。这已经修复,我不想打破这个修复!!

3 个答案:

答案 0 :(得分:4)

  1. 如果用户打开了窗口,则无法使用JavaScript关闭窗口。您只能关闭应用程序打开的新窗口。

  2. 关闭窗口对用户身份验证没有影响,因为大多数身份验证机制都依赖于服务器会话或cookie。

  3. 如果您的身份验证是基于会话的,当用户点击“注销”按钮时,您需要(1)使用户的会话无效,以及(2)重新加载您的应用,这将显示非默认的入口点 - 经过身份验证的用户(主页或登录页面)。

答案 1 :(得分:1)

Javascript只能在相同脚本打开的情况下关闭页面。所以closeWindow()甚至不会工作。所以:

  1. 如果您没有在应用中使用会话,即您认为只关闭窗口是实现的目标。然后只需从DOM中删除iframe而不是关闭页面。 (你可以使用js来做到这一点。)
  2.   

    document.getElementById('iframeid')。innerHTML ='';

    1. 如果您在应用中使用类似(通过RemoteServiceServlet)的会话,则需要首先使会话无效,然后从dom中删除元素。 (为此我不知道该怎么办。)
    2. 您可以重新加载iframe (这被视为对您应用的重新加载),而不是删除:

        

      document.getElementById('iframeid')。src =   的document.getElementById( 'iframeid')。SRC

答案 2 :(得分:0)

这是我使用的最终代码: 我在我的应用程序中使用会话(通过RemoteServiceServlet)。因此,我需要首先使会话无效,然后从dom中删除元素。所以以下是最终代码:

在客户端:

        logOutButton.addClickHandler(new ClickHandler(){
            public void onClick(ClickEvent event) {
            //Invalidate the session and then reload the application.
            AsyncCallback<Void> callback = new InvalidateSessionHandler<Void>(SelectPersonView.this);
            rpc.invalidateSession(callback);
            }
        });

class InvalidateSessionHandler<T> implements AsyncCallback<Void> {
    SelectPersonView view;

    public InvalidateSessionHandler(SelectPersonView view) {
        this.view = view;
    }

    public void onFailure(Throwable ex) {
        System.out.println("RPC call failed - InvalidateSessionHandler - Notify Administrator.");
        Window.alert("Connection failed - please retry.");
    }

    public void onSuccess(Void result) {
        //Reload the application.
        Window.Location.assign("/");    
    }
}

在服务器端:

public void invalidateSession() {
    getThreadLocalRequest().getSession().invalidate(); // kill session 
}

getThreadLocalRequest()的getSession()无效()。;将我返回到我的登录窗口。 Window.Location.assign( “/”);将我返回到tomcat页面。 所以使用哪种适合你。