Reputation: 1995
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?
Specifically in 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:
<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:
<!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(){}"
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
Thank you to all who responded. Based on your responses... I am using sessions like (via RemoteServiceServlet) in my app. Therefore, as per below in the responses, I need to invalidate session first followed by removal of element from 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!!
Upvotes: 0
Views: 1055
Reputation: 1995
This is the final code I used: I am using sessions (via RemoteServiceServlet) in my app. Therefore I need to invalidate the session first followed by removal of element from 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(); returns me to my login window. Window.Location.assign("/"); returns me to the tomcat page. So use which ever suits you.
Upvotes: 0
Reputation: 400
Javascript can only close the page if it is opened by same script. So closeWindow() won't even work. So :
document.getElementById('iframeid').innerHTML = '';
Or
Instead of removal, you can just reload the iframe (which is considered to be as a reload of your app):
document.getElementById('iframeid').src = document.getElementById('iframeid').src
Upvotes: 1
Reputation: 41089
You cannot close a window using JavaScript if the window was opened by a user. You can only close a new window that was opened by your app.
Closing window will have no effect on user authentication as most authentication mechanisms rely on server sessions or cookies.
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).
Upvotes: 4