Session management in GWT

2,914 views
Skip to first unread message

Appien

unread,
Dec 13, 2011, 8:25:38 AM12/13/11
to Google Web Toolkit
Hi folks,

I've got a question regarding session management in GWT. I'm building
an application which has several servlets. When entering the
application the application calls the so-called 'security servlet',
retrieves the userid of the request and stores this in the session
using the following code:

getThreadLocalRequest().getSession().setAttribute(label, val);

Eventually the user invokes more servlets of the applications. However
when I'm retrieving the userid from the session in those servlets
using

protected Object getFromSession(String label) {
HttpServletRequest request = getThreadLocalRequest();
if (request != null) {
HttpSession session = request.getSession();
if (session != null)
return session.getAttribute(label);
}
return null;
}

the application returns null. During debugging I found out the
sessionid of the sessions were different.

My question is: how can I manage the session information over several
request. I've the idea that using sessions is correct, however how can
I make sure the right session is used. I've already tried to increase
the time out.

Kind regards,

Jens

unread,
Dec 13, 2011, 8:48:13 AM12/13/11
to google-we...@googlegroups.com
Normally this should work out of the box with your servlet container I guess. 

Do you have a valid JSESSIONID cookie (or a similar named cookie that holds the server session id) set in your browser and will it be transmitted to your servlet container (try to log request.getCookies())?

-- J.

Ed

unread,
Dec 13, 2011, 9:19:08 AM12/13/11
to Google Web Toolkit
This has nothing to do with GWT.
Check your documentation of your servlet container.
Your web container is responsible for session management and not
touched by GWT.

You can check your session id in Chrome or FF (FireCookie) development
tools.
Note: a session id is stored in a cookie (most of the times) and a
cookie is attached to a domain (check your domain usage).
- Ed

Appien

unread,
Dec 14, 2011, 1:51:57 AM12/14/11
to Google Web Toolkit
The thing is that I use the local I use the built-in Jetty server of
GWT as development server. In the end the application will run on
JBoss. For now I want to have it working on Jetty. I've searched the
web, but I couldn't find Jetty session configure anywhere.

kim young ill

unread,
Dec 14, 2011, 3:13:11 AM12/14/11
to google-we...@googlegroups.com
try to get Request from your rpc or rf public-implementation & pass it to getFromSession()
--
You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
To post to this group, send email to google-we...@googlegroups.com.
To unsubscribe from this group, send email to google-web-tool...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.


Appien

unread,
Dec 14, 2011, 8:01:05 AM12/14/11
to Google Web Toolkit
Unfortunately this didn't work either. It is possible that is has
something to do with having multiple servlets which trying to use the
same session?

For one part of the functionality it works as it is calling the same
servlet twice...

On Dec 14, 9:13 am, kim young ill <khi...@googlemail.com> wrote:
> try to get Request from your rpc or rf public-implementation & pass it to
> getFromSession()
>

kim young ill

unread,
Dec 14, 2011, 8:04:46 AM12/14/11
to google-we...@googlegroups.com
can u post some more code  ? a bit more information would be more helpfull

Appien

unread,
Dec 14, 2011, 8:18:07 AM12/14/11
to Google Web Toolkit
Sure!

Please find below my Web.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web
Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app id="WebApp">
<display-name>ElecForms</display-name>

<listener>
<listener-class>xx.xxx.ef.server.SessionListener</listener-class>
</listener>

<!-- Servlets -->
<servlet>
<servlet-name>glsService</servlet-name>
<servlet-class>xx.xxx.ef.server.GlsServiceImpl</servlet-class>
</servlet>
<servlet>
<servlet-name>formService</servlet-name>
<servlet-class>xx.xxx.ef.server.FormServiceImpl</servlet-class>
</servlet>
<servlet>
<servlet-name>pcsService</servlet-name>
<servlet-class>xx.xxx.ef.server.PcsServiceImpl</servlet-class>
</servlet>
<servlet>
<servlet-name>mapService</servlet-name>
<servlet-class>xx.xxx.ef.server.MapServiceImpl</servlet-class>
</servlet>
<servlet>
<servlet-name>settingsService</servlet-name>
<servlet-class>xx.xxx.ef.server.SettingServiceImpl</servlet-class>
</servlet>
<servlet>
<servlet-name>securityService</servlet-name>
<servlet-class>xx.xxx.ef.server.SecurityServiceImpl</servlet-class>
</servlet>
<servlet>
<servlet-name>pdfService</servlet-name>
<servlet-class>xx.xxx.ef.server.PdfServiceImpl</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>pdfService</servlet-name>
<url-pattern>/electronicformsjboss/pdfService</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>glsService</servlet-name>
<url-pattern>/electronicformsjboss/glsService</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>formService</servlet-name>
<url-pattern>/electronicformsjboss/formService</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>securityService</servlet-name>
<url-pattern>/electronicformsjboss/securityService</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>pcsService</servlet-name>
<url-pattern>/electronicformsjboss/pcsService</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>settingsService</servlet-name>
<url-pattern>/electronicformsjboss/settingsService</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>mapService</servlet-name>
<url-pattern>/electronicformsjboss/mapService</url-pattern>
</servlet-mapping>


<session-config>
<session-timeout>30</session-timeout>
</session-config>


<!-- Default page to serve -->
<welcome-file-list>
<welcome-file>test.html</welcome-file>
</welcome-file-list>

</web-app>

All these servlet extends a custom class called BaseRemoteServiceImpl
which extends RemoteServiceServlet.

On the onModuleLoad of the application the application checks if for a
certain parameter called login. The application does an RPC call with
the loginkey as parameter and checks if it is valid. If it valid, the
application stores it in the session. The getfromsession and the
saveinsession is a function in the BaseRemoteServiceImpl. Is it
possible that the values are not overwritten if the variable is
already stored in the session?

The onModuleLoad

securityService.getCredentials(Window.Location.getParameter("login"),
new AsyncCallback<HashMap<String, String>>() {
public void onFailure(Throwable arg0) {
new AlertDialog(EFCONSTANTS.Error() + arg0.getMessage()).show();

}

public void onSuccess(HashMap<String, String> creds) {

if (creds.get(EfConstants.USER) != null &&
creds.get(EfConstants.USER).trim().length() > 0) {
waitBox.hide();
HomePage homePage = new HomePage();
homePage.init();

} else {
waitBox.hide();
new AlertDialog(EFCONSTANTS.NoAccess()).show();
}
}
});

SaveInSession function

protected void addToSession(HttpSession session, String label, Object
val) {
// Reset parameters in session.
//log.info("Saving in sessionid: " +
getThreadLocalRequest().getSession().getId() + " - label: " + label +
" - val: " + val.toString());
session.setAttribute(label, val);

}

GetFromSession function
protected Object getFromSession(HttpSession session, String label) {

if (session != null)
return session.getAttribute(label);

return null;
}

Please let me know if you need more information. Many thanks!

kim young ill

unread,
Dec 14, 2011, 8:44:17 AM12/14/11
to google-we...@googlegroups.com
in your securityServiceImpl.getCredentials() you should get Session via: getThreadLocalRequest().getSession(), then pass it to

addToSession(HttpSession session, String label, Objectval)
you here u have session, why called getThreadLocalRequest().getSession() the second time ?

Appien

unread,
Dec 14, 2011, 10:15:34 AM12/14/11
to Google Web Toolkit
Hi,

i've several call to getsession in the implementaiton of
getcredentials. Does this mean the application creates a new session
everytime i do this call? find below my code of getcredentials. I've
changed the code so everytime a method of a servlet gets first the
session by using: HttpSession session =
this.getThreadLocalRequest().getSession();


HttpSession session = this.getThreadLocalRequest().getSession();
log.info("Invoking SecurityService");
final HashMap<String, String> returnedValues = new HashMap<String,
String>();

clearLoginVariables(session);

BigInteger XXXNummer = null;
// Check if a valid parameter is given
if (null != loginKey) {
loginKey = loginKey.toLowerCase();
final IsValidKey loginWaarden = getLoginValues(loginKey);

if (null != loginWaarden) {

XXXNummer = loginWaarden.getXXXNummer();
if (XXXNumber != null) {
returnedValues.put(EfConstants.GAUSER, "" +
loginWaarden.getXXXNumber());
} else {
log.warn("XXX Number not found for loginkey :" + loginKey);
}
if (null != loginWaarden.getAbonnmentscode()) {
returnedValues.put(EfConstants.GAROLE,
loginWaarden.getAbonnmentscode());
} else {
log.warn("XXX Role not found for loginkey :" + loginKey);
}

} else {
log.warn("LoginService did not return a valid result for key: " +
loginKey);
}
// IF no parameter is in the url get the xx variable and
} else {

String XXXNumberString = getXXXNumber(session);
if (XXXNumberString != null) {
XXXNumber = new BigInteger(XXXNumberString);
returnedValues.put(EfConstants.xxxx, XXXNumber.toString());
} else {
log.warn("XXX Number not found by getting headers :" + loginKey);
}
if (getXXXRole(session) != null)
returnedValues.put(EfConstants.xxx, getXXXRole(session));
else
log.warn("XXX Role not found by getting headers :" + loginKey);

}
if (XXXNumber != null) {
log.info("XXX Member: " + XXXNumber + " logged in.");
xxx response = getxxxData(XXXNumber, getXXXRole(session));
determineFormAccess(response);
}
// Add the variables to the session
if (returnedValues.get(EfConstants.GAUSER) != null) {
addToSession(session, EfConstants.xxx,
returnedValues.get(EfConstants.xxx));

if (returnedValues.get(EfConstants.xxxx) != null) {
addToSession(session, EfConstants.xxx,
returnedValues.get(EfConstants.xxx));
}
} else {
log.warn("Session invalid");
invalidateSession(session);
}

return returnedValues;

kim young ill

unread,
Dec 14, 2011, 3:40:42 PM12/14/11
to google-we...@googlegroups.com
no, this.getThreadLocalRequest().getSession() will create one if it doesnt exist yet. once created, u'll get the same session. if the request has a valid cookie which corresponds to a existed session, there'll no new session created.

hth

but if u call it at different place , due to threading, u'll prob. get different result. so call it once at the method which is also declared at rpc-client-interface & passe it around for your request scope.

Albert van Veen

unread,
Dec 15, 2011, 8:49:00 AM12/15/11
to google-we...@googlegroups.com
Hi Kim,

thanks for your feedback so far. Unfortunately without any luck so far. Appearantly the session is only saved for the time the servlet call is running and not for the time 

I've tried 2 different setups.

I've eight servlets which all extend BaseServlet e.g. AServiceImpl and BServiceImpl etc.

For my first approach I've created a class variable HttpSession which is a property of BaseServiceImpl and accessible by the getSession method.

protected HttpSession getSession() {
if(session==null)
session =  this.getThreadLocalRequest().getSession();
return session;

}

For the second approach i've removed the session variable of the BaseServiceImpl class and changed the getsession as below.

protected HttpSession getSession() {

return this.getThreadLocalRequest().getSession();

}

Unfortunately both solutions didn't work.

i've also a session listener implemented which is below. Maybe this is causing the issue?



import java.util.Map;

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

public class SessionListener extends BaseRemoteServiceImpl implements HttpSessionListener {

public void init(ServletConfig config) {
}

/**
* Adds sessions to the context scoped HashMap when they begin.
*/
public void sessionCreated(HttpSessionEvent event) {

HttpSession session = event.getSession();

session.setMaxInactiveInterval(3);
ServletContext context = session.getServletContext();
Map<String, HttpSession> activeUsers = (Map<String, HttpSession>) context.getAttribute("activeUsers");
if (activeUsers == null) {
activeUsers = new HashMap<String, HttpSession>();
context.setAttribute("activeUsers", activeUsers);
}
System.out.println("Session created: " + session.getId());

activeUsers.put(session.getId(), session);
}

/**
* Removes sessions from the context scoped HashMap when they expire or are
* invalidated.
*/
public void sessionDestroyed(HttpSessionEvent event) {
HttpSession session = event.getSession();
System.out.println("Session destroyed: " + session.getId());
ServletContext context = session.getServletContext();
Map<String, HttpSession> activeUsers = (Map<String, HttpSession>) context.getAttribute("activeUsers");
if (activeUsers != null) {
activeUsers.remove(session.getId());
}

}
}

Jens

unread,
Dec 15, 2011, 9:03:30 AM12/15/11
to google-we...@googlegroups.com
In your session listener:

session.setMaxInactiveInterval(3);

means that after 3 seconds without any request to your server, your server will invalidate your session. So if you make the first request a new session will be created. If you then wait 3 seconds before doing the next request, you will get a new empty session because the previous one will be invalidated by your server.

So you should remove the line or increase the time significantly. 

-- J.

Albert van Veen

unread,
Dec 27, 2011, 2:33:06 AM12/27/11
to google-we...@googlegroups.com
Auch, that looks kind of obvious:(. That did the trick. Thanks all for your help. 


-- J.

--
You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
Reply all
Reply to author
Forward
0 new messages