I have a legacy Java 1.6 running localhost with Tomcat 7 application using JSP pages, a frameset with frames, javascript, but no framework like Struts. I pass an object to display in the page from the servlet using the request or session and that works fine.
However, I made some changes recently and now I can't retrieve that same object back from the session or request. It had been working fine previously, so I'm not sure what is broken, but I can't even send a string value back from the JSP's back to the servlet.
I created a new stripped down JSP and I can't get anything back from that either using the request or session. It does the same thing when I push the code our Tomcat 6 web server. Using the debugger, I see the objects populated in the session, but then lost later when a new session is created each time as in using this simple code to get the sessionid:
System.out.println("The session id is: " + session.getId());
The session id is: EB431C19B41957B2BB2EFC3DBAF32241
The session id is: C9CBD30E84D5C93DF6114C1412AE5523
I then see this in firebug under the Header, response headers:
Set-Cookie JSESSIONID=C9CBD30E84D5C93DF6114C1412AE5523; Path=/Name omitted here/; HttpOnly,
so I know cookies are set. I also removed jquery and I"m stripping down the jsp code as much as possible, but that doesn't seem to be the issue.
I'm using:
HttpSession session = request.getSession(true); but using false didn't matter.
session.setAttribute("ObjNameList", objNameList);
The context.xml has cookies set to true and we do use response.sendRedirect, but only if an error is thrown as in: response.sendRedirect("Error.jsp"); There is no place in the code with session invalidate either.
All I'm doing from the jsp is sending a form back using something like:
document.formName.submit(); which works fine. Using this code to try and set a simple string in the session doesn't work either:
session.setAttribute("somevalue","someValue");
Gives me null in the servlet here:
String val = (String) session.getAttribute("somevalue");
Any ideas as to what could be causing this?
Resultion:
It turned out to be an issue with the url, a typo actually, as BalusC mentioned, so the path for the session cookies didn't match between the jsp and the servlet.
Doublecheck if the request URL to that servlet matches the session cookie domain and path. If it doesn't match, then the browser simply won't send the session cookie back along with the request and the server will think that there's no means of an established session and will therefore simply create a new one.
You can check cookies in the HTTP traffic monitor of browser's web developer toolset (press F12 in Chrome/Firefox23+/IE9+ and open "Network" tab). When a new session starts, the server must have returned a response with Set-Cookie header with therein the cookie value and path (and implicitly domain). When the browser sends a subsequent request on the same domain and path, then it must have passed that cookie back via Cookie request header.
See also:
How do servlets work? Instantiation, sessions, shared variables and multithreading
Related
I am creating a Login Application in JAVA.I am making the presentation in JSP and all the logic (Database connectivity) in Servlet [this is not a right approach I know that].
I check the username Password in Servlet and then create a session variable.
and add the session like this
sess.setAttribute("username",oName);
Then I redirect the user to its homepage say student.jsp
response.sendRedirect("student.jsp");
It removes the session variable.I need a way to preserve the session variable and move to student.jsp.I tried to use forwading but that didn't worked out.
RequestDispatcher dispatcher =
getServletContext()
.getRequestDispatcher("/student.jsp");
if (dispatcher != null) {
dispatcher.forward(request, response);
}
It forward request but the Page address doesn't change to student.jsp which is not good.
Any help in this regard will be appreciated
Thank you
For the redirected request to come back and attach to the same session, it needs a session ID, usually carried in a JSESSIONID (or another name) cookie or in the URL as a parameter.
This cookie or URL parameter should be added by the servlet container and you should not have to add it yourself.
If you do not see the cookie in your browser, and you are not attaching the JSESSIONID to the URL, then it is creating a new session with each request, and not attaching to the same session.
Try to edit your tomcat context.xml file and replace <Context> tag to <Context useHttpOnly="false"> , this helped me.
Some browsers like Chromium for instance do not allow cookies from localhost or IP addresses, so the session cannot be preserved and changes on every refresh. This can be easily checked with the browser developer tools that show all cookies of the request.
For development, set up your workstation to resolve some more serious name (like host.kitty.com) into localhosts. Under Linux, just add entry to /etc/hosts.
Use the RequestDispatcher and set your username variable using request.setAttribute(). In this case the dispatcher will not create a new request but the same request will be forwarded using the forward() method.
We have the following situation:
JSESSIONID is being sent by both cookies and URL, but because of a Adobe Flash BUG, they are different (actually, the cookie JSESSIONID is wrong).
What we would like to do is to use the URL JSESSIONID instead of the one sent in the cookies. In other words, when I execute request.getSession(), it should return the HttpSession associated to the ID in the URL and not in the cookie.
We looked into Tomcat7 source code and, in fact, Tomcat first parses the URL, searching for an identifier. Then it overrides it with cookies SESSIONID if they are present. Here is the code snipped in CoyoteAdapter.java (tomcat 7.0.26):
String sessionID = null;
if (request.getServletContext().getEffectiveSessionTrackingModes()
.contains(SessionTrackingMode.URL)) {
// Get the session ID if there was one
sessionID = request.getPathParameter(
SessionConfig.getSessionUriParamName(
request.getContext()));
if (sessionID != null) {
request.setRequestedSessionId(sessionID);
request.setRequestedSessionURL(true);
}
}
// Look for session ID in cookies and SSL session
parseSessionCookiesId(req, request);
parseSessionSslId(request);
We could disable cookies JSESSIONID at all, but we can't because we use it for all URLs in the website. We'd like to disable cookies for JUST THIS SPECIFIC URL.
Is it possible? Is there any other idea or workaround to solve this problem?
You could implement a custom servlet filter that would replace request, response and session objects with your own wrappers. The wrappers then can behave differently based on the URL, e.g. delegate or not to the original session instance. Though you won't be able to access session data for some other id, without changing Tomcat code.
I have a very basic question how the creation of HTTPSession works.I know you folks will fire me on looking at this question as similar kind
of questions exist.But there is reasoning why i am asking this question Here it is :-
I know httpsession is unique to web browser and server creates it when we do HttpServletRequest.getSession first time.It will maintaintain the same session till we
close the browser. But i have little bit different scenario.I Have a web application on one tomcat instance say T1.On welcome page of this web application
i have provided two links on click of which takes me to same java servlet(S1) of different web application hosted on another tomcat instance T2 (these two links
opens two seperate pop up windows). Now first i click the link1 and inspect the sessionId in S1 and find its value as 1678. Now first i click the link2 and
inspect the sessionId in S1 and find its value again as 1678. My question here is why i am getting the same session id for both the requests origintaing
from link1 and link2? what can i do to to get the different session for both of these requests?
What i tried after looking for possible solutions on net :- On click of link1, in Servlet S1 , i copied session attributes, invalidate it and create new one.
Say new session id is 8765 . Now i click the link2 and found the same session in this request too. So i further invalidate it and creates new one(say
new session id is 4897). Ideally it should expire the first browser session (generated on click of link1). To verify it,i click anywhere on pop up 1 it does not get
expired but i see again last generated session id i.e 4897. I am not getting why it attaching the same session id with both pop up windows?
Folks Thanks for your patience for taking your time out and read this long scenario?
Edit :-
Cookie[] cookies = req.getCookies();
if(cookies!=null)
for (int i = 0; i < cookies.length; i++) {
cookies[i].setMaxAge(0);
context.getResponse().getHttpServletResponse().addCookie(cookies[i]);
}
HttpSession myAppSession = req.getSession();//line 1
Assume on click of link1 i get session id as 1234,then after click of link 2 also i get the same session id. As per my understanding, after executing the code above line 1 , i should get the different session id as i am setting the MaxAge as0 before getting the session. But its not happening?
I think this is what you are looking for :
By default session tracking happens by cookies. WebServer sends the session id to the browser in the form of cookie. And, the browser send the cookie having session id for the subsequent requests.
How does the browser identifies which cookies to send for a link/request?
It is based on the these parameters. If the request matches these paramters the browser sends that particular cookie:
Domain: The domain name to which the request is made. Verify in your case if the domain name is same for two instances
Path: If the path name is same. Web Server send the context root as the path , requests under same context root share cookies.
Secure: Server sends if the given cookie is secure or not. Meaning, if the cookie can be sent on non-secure channel.
These parameters will let the browser to send the cookies to the server. And because the same cookie is sent for both the instances you are having. I think the session id is being shared.
If the request propeties such as Request URI, domain and path(i.e, context root) are same between requests, there is no way to tell the browser to use different cookies.
You have some options below:
Use different domain names.
Use different context roots.
Have a LB in front of two nodes and redirect to the correct node based on Session id
I'm trying to invalidate/expire an insecure cookie from a securely accessed servlet and send a redirect back to the client. However, when the redirect is followed, the request still contains the original, unexpired, uninvalidated (is that a word) cookie.
Here's a more detailed description of the flow:
1) Client requests a particular insecure url backed by Servlet A.
2) Servlet A detects that there is a Cookie XX and redirects to a secure url backed by Servlet B
3) Servlet B does its magic, then invalidates Cookie XX by setting the MaxAge to 0 and redirects to Servlet A via an insecure url.
4) In Servlet A, I'm still able to access the cookie just as it was in the first request.
Can anyone lend a hand? I was under the impression and can't find evidence to the contrary that when a cookie is sent back with a redirect response, it is still processed before the new request is sent out. This is happening in all browsers (Chrome, FF, IE) that I have access to, so I don't think its a browser thing. In HTTPFox and the Chrome Developer tools I can see the original cookie getting sent in the first and second request, the invalidated cookie coming back in the response to the second request, and the original cookie being sent again in the third request. I've tried setting the MaxAge to 0, setting the value of the cookie to null/empty string, and another value but it never changes. All of the server side code is done in Java if it matters.
Help is very much appreciated.
Have you tried making sure that the domain and paths for the invalidated cookie is the same as the original cookie?
Also, a better way to handle sensitive cookies is setting the 'secure' flag on the original cookie. That will tell the browser to never send the cookie over an insecure connection.
This turned out to be an oversight on my part. When Servlet B invalidated Cookie XX, it also set the cookie's path to something other than what it originally was. That, in effect, created a Cookie XX-B and had no effect on the original Cookie XX. Making sure my cookie's paths were the same fixed it.
In two separate projects I've had to invalidate a cookie. This is what I have had to do:
Get the cookie in question from the HTTP request object
Set cookie max age to by invoking Cookie.setMaxAge(int).
Call the Cookie.setPath(String) method, even if path is to remain the same
Add the cookie back into the HTTP response object, I.e. HttpServletRespons.addCookie(cookie)
Only after executing all the steps above did the browser stop passing the cookie back to server on subsequent requests.
it seems that the Parameter-Name in the GET request, that represents the SessionID (like jsessionid=XXXXXXXXXXXXXXXXXXXXXXXXXX in Tomcat) is not standardized in the servlet-spec? How can I get the (Servelt Container Specific) name of the SessionID? (At least in Websphere there seems to be the possibilty to change the name of the SessionID-Parameter-Name)
=> The underlaying problem is, I need to encode a URL in a servlet ALWYAS with the session ID. But it seems that the "response.encodeURL()" Method only does this if Cookies are disabled (=>therefor using URL-Rewriting with the sessionID in the URL).
What would be an alternative to always encode a URL with a session ID in a servlet? As the first question implies I wanted to build the sessionid on my own but I therefore need the sessionID-Parameter Name that however seems not be be standardized, so I somehow need to get the Parameter-Name from somewhere...)
UPDATE:
The intention is to keep the SessionManagement Functionality provided by the Servlet-Container and not turn it off completely. I need to pass a Callback URL to a third party system that I want to always contain the SessionURL. So I only want to encode this single URL always with the sessionID to minimize any security issues...
Thank you very much
Jan
The jsessionid isn't actually a request parameter, it's encoded on to the URL itself, and then decoded and removed by the container before it gets as far as your controller. The value of jsessionid itself can be retrieved from HttpSession.getId().
If you want to stop Tomcat from using cookies, then you can provide a tomcat-specific context.xml file under WEB-INF, containing something like this:
<Context cookies="false" path="/path/to/my/webapp">
</Context>
This will disable all cookies for that webapp, and tomcat should then automatically encode all session IDs on to the URL instead.