Link to home
Start Free TrialLog in
Avatar of nateforrest1
nateforrest1

asked on

Maintaining Session Problem - Struts and Tomcat

My Struts application (running on Tomcat 5.5.9) does appear to be maintaining the user's session.  I first noticed that information put into the session was not available after the next call to another Struts Action Servlet.  Looking into it more I found that after each Struts action is performed a new JSESSIONID is created (this was confirmed both by adding logging to the Action classes and inspecting the cookies).  Is there a setting I am missing in Tomcat?

From the web.xml file:
    <session-config>
        <session-timeout>30</session-timeout>
    </session-config>

From one of my Action classes:
<code>
public class CitySearchAction extends Action {
    private static Logger log = Logger.getLogger(CitySearchAction .class);
   
    public ActionForward execute(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response) {
       
        ActionMessages messages = new ActionMessages();
        ActionForward forward = new ActionForward();
       
        try {
            log.info("CitySearchAction: Starting...");
            HttpSession session = request.getSession();
            log.info("session = " + session.getId());
...
</code>
Avatar of avinthm
avinthm

Hi ,

> HttpSession session = request.getSession();
Instead use
HttpSession session = request.getSession(false);

If the request has valid session then current session is returned, else returns null.

cheers
Seems that you have the same problem with this question: LOST SESSION
https://www.experts-exchange.com/questions/21735739/How-to-solve-session-null-in-servlet.html
Do like avinthm said, just to know that the sessino is NULL or not only
Avatar of bloodredsun
>>Is there a setting I am missing in Tomcat?

It depends. If you have set not to use Cookies in session tracking then you will need to use url rewriting to persist the session so that it looks like this "/myAction.do;jsession=kwewew2132341234"\
Avatar of nateforrest1

ASKER

In each Action class I modified the HttpSession session = request.getSession(); to :

HttpSession session = request.getSession(false);
if(null != session) {
    log.info("sessionID = " + session.getId());
}
else {
    // Create a new session if the old is null.
    session = request.getSession(true);
}

Its still not working.  Each time the session was not null and a different session id was printed.  I am currently using the embedded Tomcat 5.5.9 server in Netbeans 5.  I know that cookies are being created as I can view them after each request in my browser.  I'm also using Apache to rewrite the urls into something that might be indexed properly such as http://localhost/Test/citylist.do?city=miami&state=FL&country=US into http://localhost/Test/Miami/FL/US, but I'm not using it to persist the session data.  I've read some sites that say to use caution when doing this.
You should really use mod_jk to connect Tomcat to Apache rather than mod_rewrite. It appears that this is may well be the root cause.
I think you're right.  I am such a newbie to this SysAdmin role thrown at me! This may be the cause of my problem, although I'm not sure how to fix it.  I actually thought I was using mod_jk to connect to Apache to Tomcat.  Initially when I installed Apache I added the following a couple of lines to my server.xml file:

<Listener className="org.apache.ajp.tomcat5.config.ApacheConfig" modJK="c:/ApacheGroup/Apache2/modules/mod_jk.so"/>
<Listener className="org.apache.ajp.tomcat5.config.ApacheConfig" append="true" forwardAll="false" modJK="c:/ApacheGroup/Apache2/modules/mod_jk.so"/>

However, I commented both of these out, restarted the server and the application worked as it normally did.  The rewrite rules in my httpd.conf file under Apache are still working.  Any idea how to set it up properly to use the mod_jk connector, but keep the ability to use the rewrite rules?

It should all be in the mod_jk documentation.
http://tomcat.apache.org/connectors-doc/ or http://johnturner.com/howto/apache-tomcat-howto.html

Using mod_jk, only affects the urls that you map in the httpd.conf as in this example

  # send all requests ending in .jsp to worker1
  JkMount /*.jsp worker1
  # send all requests ending /servlet to worker1
  JkMount /*/servlet/ worker1
  # send all requests jsp requests to files located in /otherworker will go worker2
  JkMount /otherworker/*.jsp worker2

The only ones affected are /*.jsp, /*/servlet/ and /otherworker/*.jsp . This means that your rewrite rules are unaffected as they are completely separate.
Sorry this turned into a Server issue, but the help is greatly appreciated.

Currently in the httpd.conf file I have the following:

LoadModule jk_module modules/mod_jk.so

JkWorkersFile C:/netbeans-5.0rc2/enterprise2/jakarta-tomcat-5.5.9/conf/workers.properties
JkLogFile C:/netbeans-5.0rc2/enterprise2/jakarta-tomcat-5.5.9/logs/mod_jk.log
JkLogLevel debug

Alias /Test C:/workspace/Test
JkMount /Test/servlet/* ajp13
JkMount /Test/*.jsp ajp13
JkMount /Test/*.do  ajp13

I checked the mod_jk.log file and it is being written to.  The workers.properties file was the default that came with the installation of NetBeans.  Would the last JkMount tell apache to let the ajp13 worker handle a request to  http://localhost/Test/citylist.do?city=miami&state=FL&country=US?
>>Would the last JkMount tell apache to let the ajp13 worker handle a request to  http://localhost/Test/citylist.do?city=miami&state=FL&country=US?

Yes (although I'm not sure about the alias line, I presume that's correct). Issues like yours almost always end up being server issues, it's just part of web development so don't sweat it:-)
I added logging to the Action class for information about the session.

        try {
            log.info("CitySearchAction: Starting...");
log.info("from cookie = " + request.get
I added loggin to the Action class for information about the session.

       try {
            log.info("CitySearchAction: Starting...");
            log.info("requested id = " + request.getRequestedSessionId());
            log.info("from cookie = " + request.isRequestedSessionIdFromCookie());
            log.info("from url = " + request.isRequestedSessionIdFromURL());
            log.info("id valid = " + request.isRequestSessionIdValid());

            Cookie[] cookies = request.getCookies();
            if(null != cookies) {
                 log.info("# cookies = " + cookies.length);
            }
            else {
                 log.info("no cookies");
            }

            HttpSession session = request.getSession(false);
            log.info("is new = " + session.isNew());

The output was:

requested id = null
from cookie = false
from url = false
is valid = false
no cookies
is new = true
You get that output the first time you access the page. Unlike JSPs, servlets do not create a session by default and will not do so until you call request.getSession(true), request.getSession().

Remember also that session.isNew() returns true if the client does not yet know about the session or if the client chooses not to join the session. In this case, the former is true as you have called request.getSession(false) which only returns a session if one already exists.

You will need to call request.getSession(true) and then re-access this action.
I am calling request.getSession(true) if the client does not know about the session.  I'm getting the same result no matter if its the first, second, ... time I access the Action.

HttpSession session = request.getSession(false);
if(null != session) {
    log.info("is new = " + session.isNew());
    log.info("sessionID = " + session.getId());
}
else {
    // Create a new session if the old is null.
    session = request.getSession(true);
}

Thanks again for working with me on this!
ASKER CERTIFIED SOLUTION
Avatar of bloodredsun
bloodredsun
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
You are right.  When I disable the rewrite rules and let the action classes perform like normal the session is maintained.    I found some more information here about mod_rewrite losing the session: http://www.nabble.com/mod_rewrite-losing-session-t1178395.html

According to this thread adding emptySessionPath="true" to the Connector should fix the problem.  I tried modifying the connectors defined in my server.xml file, but it still wasn't working.  

<Connector port="8009" enableLookups="false" redirectPort="8443" protocol="AJP/1.3" emptySessionPath="true"/>


<Connector port="8080" maxHttpHeaderSize="8192" maxThreads="150" minSpareThreads="25" enableLookups="false" redirectPort="8443" connectionTimeOut="20000" disableUploadTimeout="true" emptySessionPath="true"/>

I feel like I'm close to having this fixed!
I've used mod_jk in the past and it's worked perfectly, although that was only on a dev machine wiht no mod_rewrite. The prod machine was run by a guy with much better Apache skills than me so I know it does work.

That it works fine when you disable the re-write rules indicates that your Java/JSP/mod_jk set up works perfectly (hurray!). You may need to ask a question in the Apache forum to get a quick and definitive asnwer to what rules you need to change to get them to work together.
Thanks for the help!
Cheers Nate. 1500 more points and I get my Genius certificate in this forum! Thanks for the points and the grade and good luck with this project :-)