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</sessi on-timeout >
</session-config>
From one of my Action classes:
<code>
public class CitySearchAction extends Action {
private static Logger log = Logger.getLogger(CitySearc hAction .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>
From the web.xml file:
<session-config>
<session-timeout>30</sessi
</session-config>
From one of my Action classes:
<code>
public class CitySearchAction extends Action {
private static Logger log = Logger.getLogger(CitySearc
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
ActionMessages messages = new ActionMessages();
ActionForward forward = new ActionForward();
try {
log.info("CitySearchAction
HttpSession session = request.getSession();
log.info("session = " + session.getId());
...
</code>
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
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
>>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=kwe wew2132341 234"\
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=kwe
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.
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.
ASKER
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.co nfig.Apach eConfig" modJK="c:/ApacheGroup/Apac he2/module s/mod_jk.s o"/>
<Listener className="org.apache.ajp. tomcat5.co nfig.Apach eConfig" append="true" forwardAll="false" modJK="c:/ApacheGroup/Apac he2/module s/mod_jk.s o"/>
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?
<Listener className="org.apache.ajp.
<Listener className="org.apache.ajp.
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.
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.
ASKER
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/enterpr ise2/jakar ta-tomcat- 5.5.9/conf /workers.p roperties
JkLogFile C:/netbeans-5.0rc2/enterpr ise2/jakar ta-tomcat- 5.5.9/logs /mod_jk.lo g
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?
Currently in the httpd.conf file I have the following:
LoadModule jk_module modules/mod_jk.so
JkWorkersFile C:/netbeans-5.0rc2/enterpr
JkLogFile C:/netbeans-5.0rc2/enterpr
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:-)
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:-)
ASKER
I added logging to the Action class for information about the session.
try {
log.info("CitySearchAction : Starting...");
log.info("from cookie = " + request.get
try {
log.info("CitySearchAction
log.info("from cookie = " + request.get
ASKER
I added loggin to the Action class for information about the session.
try {
log.info("CitySearchAction : Starting...");
log.info("requested id = " + request.getRequestedSessio nId());
log.info("from cookie = " + request.isRequestedSession IdFromCook ie());
log.info("from url = " + request.isRequestedSession IdFromURL( ));
log.info("id valid = " + request.isRequestSessionId Valid());
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
try {
log.info("CitySearchAction
log.info("requested id = " + request.getRequestedSessio
log.info("from cookie = " + request.isRequestedSession
log.info("from url = " + request.isRequestedSession
log.info("id valid = " + request.isRequestSessionId
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.
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.
ASKER
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!
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
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!
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
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.
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.
ASKER
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 :-)
> 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