简体   繁体   English

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

[英]GWT Java - How to close the window (Log Out)

I have read that to Log Out of the application you need to close the window and I found this code: 我读到要注销该应用程序,需要关闭窗口,然后发现以下代码:

This answer has what you are looking for: How to run JavaScript function from GWT Java with JSNI? 该答案具有您所需要的: 如何使用JSNI从GWT Java运行JavaScript函数?

Specifically in Java: 特别是在Java中:

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

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

Then in JavaScript in your app's .html page: 然后在JavaScript的应用程序的.html页面中:

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

I have implemented this in my application by: 我已经通过以下方式在我的应用程序中实现了此功能:

    //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();}-*/;

And the HTML: 和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>

However, I get the following error on the lines: 但是,我在行上收到以下错误:

closeWindow(); 

"The method closeWindow() is undefined for the type new ClickHandler(){}" “对于类型为new ClickHandler(){}的方法closeWindow()未定义”

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

Multiple markers at this line - Syntax error, insert "EnumBody" to complete BlockStatement - Syntax error on token "void", @ expected - Syntax error, insert "enum Identifier" to complete EnumHeaderName 这行有多个标记-语法错误,插入“ EnumBody”以完成BlockStatement-令牌“ void”上的语法错误,@预期-语法错误,插入“枚举标识符”以完成EnumHeaderName

Thank you to all who responded. 谢谢所有答复。 Based on your responses... I am using sessions like (via RemoteServiceServlet) in my app. 根据您的响应...我在我的应用程序中使用的会话(通过RemoteServiceServlet)。 Therefore, as per below in the responses, I need to invalidate session first followed by removal of element from dom. 因此,根据下面的回复,我需要先使会话无效,然后再从dom中删除元素。 So tried the following: 因此尝试了以下方法:

On the client side: 在客户端:

        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("/");    
    }
}

On the server side: 在服务器端:

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

This seems to work. 这似乎有效。 However, I am having trouble testing more than one session locally and I do not have a test server I can deploy to. 但是,我在本地测试多个会话时遇到麻烦,并且我没有可部署到的测试服务器。 So can I please ask for someone who knows what they are doing in this space to check it to ensure I am not introducing issues into production. 因此,我可以请一个知道他们在这个空间中正在做什么的人来检查它,以确保我不会在生产中引入问题。 My greatest concern is that this will log everyone out. 我最大的担心是,这将使所有人退出。 I am particularly toey because I had a situation where sessions were not compartmentalised and users could see other people's data. 我特别喜欢,因为我遇到这样的情况,即会话没有分隔开,用户可以看到其他人的数据。 This has been fixed and I do not want to break that fix!! 该问题已得到解决,我不想破坏该修复!!

  1. You cannot close a window using JavaScript if the window was opened by a user. 如果用户打开了窗口,则无法使用JavaScript关闭该窗口。 You can only close a new window that was opened by your app. 您只能关闭应用程序打开的新窗口。

  2. Closing window will have no effect on user authentication as most authentication mechanisms rely on server sessions or cookies. 关闭窗口对用户身份验证没有影响,因为大多数身份验证机制都依赖于服务器会话或cookie。

If your authentication is session-based, when a user clicks on the Log Out button you need to (1) invalidate user's session, and (2) reload your app, which will display default entry point for non-authenticated users (home page or login page). 如果您的验证是基于会话的,则当用户单击“注销”按钮时,您需要(1)使用户的会话无效,以及(2)重新加载您的应用,这将显示未验证用户的默认入口点(主页或登录页面)。

Javascript can only close the page if it is opened by same script. 如果Javascript由同一脚本打开,则只能关闭该页面。 So closeWindow() won't even work. 因此closeWindow()甚至无法工作。 So : 因此:

  1. If you are not using sessions in your app ie you think that only closing the window is a goal to achieve. 如果您没有在应用程序中使用会话,即您认为仅关闭窗口是要实现的目标。 Then simply delete that iframe from DOM rather closing page. 然后只需从DOM中删除该iframe,而不是关闭页面即可。 (You can do that by using js.) (您可以通过使用js来做到这一点。)

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

  1. If you are using sessions like (via RemoteServiceServlet) in your app, then you need to invalidate session first followed by removal of element from dom. 如果您在应用中使用的会话(例如通过RemoteServiceServlet),则需要先使会话无效,然后再从dom中删除元素。 (For this i am not sure how to do.) (为此,我不确定该怎么做。)

Or 要么

Instead of removal, you can just reload the iframe (which is considered to be as a reload of your app): 除了删除外,您还可以重新加载iframe (这被视为应用的重新加载):

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

This is the final code I used: I am using sessions (via RemoteServiceServlet) in my app. 这是我使用的最终代码:我在应用程序中使用会话(通过RemoteServiceServlet)。 Therefore I need to invalidate the session first followed by removal of element from dom. 因此,我需要先使会话无效,然后再从dom中删除元素。 So the following is the final code: 因此,以下是最终代码:

On the client side: 在客户端:

        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("/");    
    }
}

On the server side: 在服务器端:

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

getThreadLocalRequest().getSession().invalidate(); getThreadLocalRequest()。getSession()。invalidate(); returns me to my login window. 返回我的登录窗口。 Window.Location.assign("/"); Window.Location.assign(“ /”); returns me to the tomcat page. 让我回到tomcat页面。 So use which ever suits you. 因此,请使用最适合您的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM