How can I pass the session attribute value to another application which is in same web server. The reason why I should know this is because we have a project which is divide by a module. Each module will redirect to another that pass value using session. That session will be used to identify which user is accessing that module.
Suppose I have a LogIn Module that separate from my other module.
Here my sample code:
Sample Url http://localhost:8080/Login
authorization.jsp : This page will call after user input a userId and then submit
page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"
HttpSession sessionid = request.getSession();
String userId = request.getParameter("userId");
sessionid.setAttribute("userId", userId);
System.out.println("SESSION IS :" + sessionid.getAttribute("userId"));
response.sendRedirect("http://localhost:8080/OtherModule");
Sample Url http://localhost:8080/OtherModule
In my Home servlet I will check if the session have a userId
protected void doGet(HttpServletRequest request, HttpServletResponse response){
HttpSession session = request.getSession();
if(session.getAttribute("userId") != null){
System.out.println("SESSION ID # GET: " + session.getAttribute("userId"));
} else {
System.out.println("No Session for userId");
}
}
//I also tried this with post but still I can't get the session
I hope this information may give you idea what's wrong with my code. Please help me with this. Thanks
You will have to configure your web-server accordingly. Tomcat for example provides a valve for that. See here: http://tomcat.apache.org/tomcat-6.0-doc/config/host.html#Single_Sign_On
Note: The localhost-URL you posted, only works on your computer (hence the name "local").
It would be much easier though to just add all of your modules into one Web-Application or to use one of the countless Java Web Application Frameworks.
If your shared data is related to authentication/login, then SSO (single sign on) is the way to go as #Ridcully says - it's managed for you by the application server, and your apps shouldn't need to worry about it.
If the problem is more general - how to share data between webapps - then a very clean approach is to use JNDI. Tomcat (and any other servlet/J2EE server) provide a lookup space that can be common to all webapps, this mechanism is most often used to define database (or other resource) configuration outside apps in a way that can be shared.
So, you could write a class to contain the data, have it in JNDI, and have each application look it up (using explicit JNDI calls or resource injection). If you need more info on this let me know.
Single sign on indeed solves the shared-logged-in-user issue.
It does however not allow for sharing the same session among all deployed webapplications. If that is after all your actual intent, then you need to set emptySessionPath attribute of the <Connector> element in /conf/server.xml to true.
<Connector ... emptySessionPath="true">
See also Tomcat 6.0 HTTP Connector documentation.
Related
Is there a way to pass a parameter to a servlet going through another jsp and then to another servlet
like
jsp---parameter--->servlet(using getParameter())---parameter--->jsp---parameter--->servlet(is there a way to get the parameter here)
The program that am working on is to pass the username.
Looks like you want to use HTTPsession.
Provides a way to identify a user across more than one page request or visit to a Web site and to store information about that user.
The servlet container uses this interface to create a session between an HTTP client and an HTTP server. The session persists for a specified time period, across more than one connection or page request from the user. A session usually corresponds to one user, who may visit a site many times. The server can maintain a session in many ways such as using cookies or rewriting URLs.
Setting
Session session = request.getSession();
session.setAttribute("username", username);
getting it back
String username = (String)session.getAttribute("username");
I am experimenting with setting the cookie path in my application's web.xml (as suggested here) to:
<session-config>
<cookie-config>
<path>/</path>
</cookie-config>
</session-config>
So I deploy two identical web applications to localhost:8080/application-a and localhost:8080/application-b respectively.
Each application is a single servlet:
public class ControllerServlet extends HttpServlet{
#Override
public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
HttpSession session = req.getSession(false);
if (session == null) {
session = req.getSession(true);
System.out.printf("No session was present - new one created with JSESSIONID=[%s]\n", session.getId());
} else {
System.out.printf("JSESSIONID cookie was present and HttpSession objects exists with JSESSIONID=[%s]\n", session.getId());
}
}
}
I deploy the apps to a Tomcat 8.5 container (tried with Tomcat 9 as well the behavior is the same). When I visit with my browser the application-a, here's what I see:
… and on the Tomcat logs I read:
No session was present - new one created with JSESSIONID=[A227B147A4027B7C37D31A4A62104DA9]
So far so good. When I then visit application-b here's what I see:
… and the Tomcat logs show:
No session was present - new one created with JSESSIONID=[5DC8554459233F726628875E22D57AD5]
This is also very well as explained here and also in this answer and I quote:
SRV.7.3 Session Scope
HttpSession objects must be scoped at the application (or servlet
context) level. The underlying mechanism, such as the cookie used to
establish the session, can be the same for different contexts, but the
object referenced, including the attributes in that object, must never
be shared between contexts by the container.
So even though on the request the JSESSIONID cookie was present, my application (the one deployed in application-b) was unable to find an HttpSession object in its own servlet context scope and so a new session object was created and a new value was assigned to the JSESSIONID cookie.
However, when I now go back to my application-a I find out that because of the / value configured for the cookie path, it is now trying to use the JSESSIONID value set by application-b and of course its servlet doesn't find such a session object in its own context (application-a) and so a new value for the JSESSIONID cookie is created which will in turn invalidate the session of the application-b application and so on and so forth ad infinitum as I switch back and forth between the two applications.
So my questions are:
1 given the above behavior it would seem impossible for two applications to use the same JSESSIONID cookie value as the key to their respective HttpSession objects. So in fact not only are the HttpSession objects always different and scoped at the application (servlet context) level but also, in practice, the JSESSIONID values have to be different. Is that correct?
2 If so, then why does the servlet specification use the wording:
The underlying mechanism, such as the cookie used to establish the
session, can be the same for different contexts [...]
The only way I can imagine the above could be accomplished would be to have a way to hardcodedly provide the JSESSIONID value to use when a new session object is created? But I don't see an API for that.
3 Is there a way I can have some other cookies be shared among applications using the / path in the <session-config> XML element but not have the / path apply to the JSESSIONID cookie? In other words does the <session-config> apply to all cookies of an application or only the cookie used for session tracking? (JSESSIONID) ?
Upon further experimentation and taking a cue from this answer it would appear that for the same JSESSIONID to be used for all web applications it is necessary to set the following attribute in context.xml:
<Context ... sessionCookiePath="/">
Either the Tomcat-wide context.xml or the WAR-specific context.xml will do. The <cookie-config><path> value configured in the WAR's web.xml is apparently ignored.
Regarding point 3 of my question I 've found that the way to set paths for other cookies is to programmatically create many of them, one for each path, and add them in the response object with the addCookie method. The configurations in web.xml or context.xml are appicable to other cookies beyond the session cookie.
I am using sessions and have enabled sessions in my GAE app
<sessions-enabled>true</sessions-enabled>
<async-session-persistence enabled="true" />
I am using sessions for the purpose of a simple user login. Locally, this works just fine, my session is maintained until I logout and all my pages that are "protected" are viewable with a valid session.
The problem with my live/production server on appspot is that it doesn't work at all. When I login and authenticate, I redirect to another page. This page checks if I have a valid session (using standard HttpSession) and somehow this fails and then redirects me back to the login screen.
Does anyone have any idea why it doesn't work in the GAE production environment but works just fine locally?
Here is the code I use to check validity of current session:
public static boolean isValidSession(HttpServletRequest request) {
return (request.isRequestedSessionIdValid());
}
Update:
I'm creating session ID like this:
public static void createNewSession(HttpServletRequest request, final String username) {
HttpSession session = request.getSession(true);
session.setAttribute("username", username);
}
There is no difference between handling sessions locally and in production as such on Google App Engine. They work the same in both the environment. The only difference that I can think of is that when you create sessions (say at or after Login) locally and you set some attribute in the session say the access level of the user, it will not change even when attribute's value change(say if it is pulled dynamically from some database where it got changed after Login) until you close the tab and Login again, however in production if the attribute changes in the database and then if you refresh the page it will take the new value from the database. Well that's in my experience. Hope it helps.
My question is:
I have two different Portlets (nothing but war file) deployed in a portal server called first and second; whenever user clicks firstportlet (first) I use the following code to set session object!:
Code in first portlet:
String application="Welcome";
PortletRequest portletRequest = (PortletRequest) webAppAccess
.getHttpServletRequest()
.getAttribute(Constants.PORTLET_REQUEST);
portletRequest.getPortletSession(true).setAttribute("application",
sessionValue,
PortletSession.APPLICATION_SCOPE);
log.Info("SESSION hole value:---" + portletRequest.getPortletSession(false));
Whenever user clicks secondportlet(second) I am using follwing code to retrieve the session which was set in firstportlet.
Code in second portlet:
PortletRequest portletRequest = (PortletRequest) webAppAccess
.getHttpServletRequest()
.getAttribute(Constants.PORTLET_REQUEST);
log.Info("SESSION hole value:---"+ portletRequest.getPortletSession(false));
log.Info("SESSION VALUE in second Portlet:----"
+ portletRequest.getPortletSession(false).getAttribute("application",
PortletSession.APPLICATION_SCOPE));
Error:
But in second portlet I am always getting null value, please any solution?
The portletSession.APPLICATION_SCOPE mechanism makes it possible for portlets to share session data if they are within the same portlet application. If you have two portlets that are not in the same war they are not in the same portlet application and thus, the session data is not shared either.
To solve this you need to put the two portlets into the same portlet application (same war, same portlet.xml but still two different portlets).
DanielBarbarian's answer is correct. To share the global session, the portlets need to be in the same war. But there are other ways to share data between portlets on the same page, but not necessarily in the same war. (I'm assuming your portal container supports the JSR286 standard)
Use interportlet communication. This can notify other portlets of events. It is a simple publish/subscribe system that is not difficult to set up.
Use global render parameters.
There are examples on the web for both options.
I would like to know if there is some way to share a variable or an object between two or more Servlets, I mean some "standard" way. I suppose that this is not a good practice but is a easier way to build a prototype.
I don't know if it depends on the technologies used, but I'll use Tomcat 5.5
I want to share a Vector of objects of a simple class (just public attributes, strings, ints, etc). My intention is to have a static data like in a DB, obviously it will be lost when the Tomcat is stopped. (it's just for Testing)
I think what you're looking for here is request, session or application data.
In a servlet you can add an object as an attribute to the request object, session object or servlet context object:
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
String shared = "shared";
request.setAttribute("sharedId", shared); // add to request
request.getSession().setAttribute("sharedId", shared); // add to session
this.getServletConfig().getServletContext().setAttribute("sharedId", shared); // add to application context
request.getRequestDispatcher("/URLofOtherServlet").forward(request, response);
}
If you put it in the request object it will be available to the servlet that is forwarded to until the request is finished:
request.getAttribute("sharedId");
If you put it in the session it will be available to all the servlets going forward but the value will be tied to the user:
request.getSession().getAttribute("sharedId");
Until the session expires based on inactivity from the user.
Is reset by you:
request.getSession().invalidate();
Or one servlet removes it from scope:
request.getSession().removeAttribute("sharedId");
If you put it in the servlet context it will be available while the application is running:
this.getServletConfig().getServletContext().getAttribute("sharedId");
Until you remove it:
this.getServletConfig().getServletContext().removeAttribute("sharedId");
Put it in one of the 3 different scopes.
request - lasts life of request
session - lasts life of user's session
application - lasts until applciation is shut down
You can access all of these scopes via the HttpServletRequest variable that is passed in to the methods that extend from the HttpServlet class
Depends on the scope of the intended use of the data.
If the data is only used on a per-user basis, like user login info, page hit count, etc. use the session object
(httpServletRequest.getSession().get/setAttribute(String [,Object]))
If it is the same data across multiple users (total web page hits, worker threads, etc) use the ServletContext attributes. servlet.getServletCongfig().getServletContext().get/setAttribute(String [,Object])). This will only work within the same war file/web applicaiton. Note that this data is not persisted across restarts either.
Another option, share data betwheen contexts...
share-data-between-servlets-on-tomcat
<Context path="/myApp1" docBase="myApp1" crossContext="true"/>
<Context path="/myApp2" docBase="myApp2" crossContext="true"/>
On myApp1:
ServletContext sc = getServletContext();
sc.setAttribute("attribute", "value");
On myApp2:
ServletContext sc = getServletContext("/myApp1");
String anwser = (String)sc.getAttribute("attribute");
Couldn't you just put the object in the HttpSession and then refer to it by its attribute name in each of the servlets?
e.g:
getSession().setAttribute("thing", object);
...then in another servlet:
Object obj = getSession.getAttribute("thing");
Here's how I do this with Jetty.
https://stackoverflow.com/a/46968645/1287091
Uses the server context, where a singleton is written to during startup of an embedded Jetty server and shared among all webapps for the life of the server. Can also be used to share objects/data between webapps assuming there is only one writer to the context - otherwise you need to be mindful of concurrency.