I am writing one application, on that i am setting user object into a session and i cannot able to get that session into another controller. And i want to maintain that session throughout the application(Until the user logout). So how can i get the session object into another controller and throughout the application. And what are the steps that i need to follow to maintain the session throughout the application.
Setting into session:
public ResponseEntity<Object> getCustMenus(HttpSession session){
UserInformation userInformationSession = luser.getRolesData();
session.setAttribute("userInfo", userInformationSession);
}
Getting the session:
UserInformation userInformation=(UserInformation) session.getAttribute("userInfo");
System.out.println("-----"+userInformation.getUserName()+"----------username");
I came across your question, because I'm also facing the same problem.
I think we can rely on Tomcat's request handling mechanism - each request is running in a single thread.
So I can have
Static map where key is the request Thread object and value is the Httpsession or even HTTpRequest object. Map
Filter with url set to /* which means each request passes through this filter. The filter will add the current thread and request object to the static map.
map.put(Thread.currentThread(), httpRequest);
As the map is a static field of some class it will be accessible to all threads and if you need to share an object between different controllers though lifecycle of a request you can put it in this map, e.g. put in httpsession as an attribute and get it anywhere you want.
In filter remove the thread from map when request is done.
map.remove(Thread.currentThread());
In case we use WeakHashMap I suppose we can skip step 3.
I haven't tried this approach yet, but I think it should work. I will share results when I try it.
I found complete answers in another discussion. Get the HttpServletRequest (request) object from Java code
The most useful part of the discussion for me was posted by skaffman. Please find it below.
Spring provides the RequestContextFilter for just this purpose. It uses ThreadLocal, and allows the code to fetch the current request via RequestContextHolder. Note that this filter does not require you to use any other part of Spring:
Related
Objective
When a person creates a resource (no need to connect), she receives a unique token, which she must then transmit to each request she sends for information about her resource.
Question
There is a simple way to do that with Spring? Indeed, all tuto I found and read used an authentification with username and password.
Already tried
My first idea was to create a token at the end of POST methods (store it into database), put it into each GET requests and check if requestToken == databaseToken.
However, I don't think that's the best way to do it.
So, can you help me and advise me to solve the problem?
Thanks a lot!
There are multiple ways.
Using the #SessionAttributes annotation:
The first time our controller is accessed, Spring will instantiate an instance and place it in the Model. Since we also declare the bean in #SessionAttributes, Spring will store the instance.
You will get it inside controller's handler method thru #ModelAttribute.
Or, you can try this route:
#RequestMapping(value = "/test")
public String handler(HttpSession httpSession) {
httpSession.getId(); //this will give you unique identifier that you can set back to object that you send to front end and can share the same ID between requests.
}
https://docs.oracle.com/javaee/7/api/javax/servlet/http/HttpSession.html#getId--
I have a very simple JSP page where it has one search box and based off the input, in the search box, it will return a response with a submit button to get the following response.
I noticed that whenever I use request.getattribute("foo") in my servlet to retrieve some request it returns null due to the request ending so I looked at the answers on here and started using session.getattribute("foo") instead. However, now I am stuck having session variables responses being set and it is causing my view to have old session data that isn't suppose to be there so now I have to use session.removeAttribute("foo"), whenever, I don't want that particular response data to be shown.
Is there a better way to go about managing this instead of having to use session.getattribute("foo"), session.removeAttribute("foo") and session.setattribute("foo")?
You should work with request.getSession()
Returns the current session associated with this request, or if the request does not have a session, creates one.
Set an attribute:
request.getSession().setAttribute("foo")
And get attribute using:
request.getSession().getAttribute("foo")
It will be used in the context of the request and not effect other requests, so you don't need to remove attribute.
Read more in Servlets tutorial
Servlets provide an outstanding technical solution: the HttpSession API. This is a high-level interface that allows the server to "remember" a set of information relevant to a particular user's on-going transaction, so that it can retrieve this information to handle any future requests from the same user.
You can go for request.getparameter("foo") or request.setparameter("foo", obj)
This can be used for every request, and it will not add to your session variables and basically will not make your "session object heavy".
Java doc:
Request parameters are extra information sent with the request. For HTTP servlets, parameters are contained in the query string or posted form data.
Well, this is from a developer newly using Play. When it came to using session, I found its not at all like I have been doing in servlets or jsps.
I have tried reading documentation and found session in Play are stored in HTTP cookies rather. I have tried importing HTTP class of play.
My problem however is I am unable to initialise a new session to set values in it.
I have obviously tried using 'new' session as in Java and that obviosly didnt work out.
Session session = new session();
Also after looking somewhere I have used:
Session session = Http.Context.current().session();
which shows me error in identifying context and current
I have tried looking at sample codes and codes on net. each of them however is different and I don't get the basic way of using sessions in Play, so that after that I can use put and get to keep and retrieve.
I know the question seems too basic but believe me there is no exact answer available anywhere to what I need. So please help me regarding this.
Any answer, any piece of code, or any Link on this will be highly appreciated.
Forget everything about the sessions from the jsp and servlets world while working with the Play's session. Play doesn't store anything on the server side and by design it's completely stateless. The Play session is just a cookie attached to every http request and it's stored on the client side. Word 'session' may be misleading in your case.
Working with the session is pretty straight forward. All you need is inherited from play.mvc.Controller which you have to extend when creating your own controller. To put a value in it you simply call the session(String key, String value) method from within a controller. For example:
public class Application extends Controller {
public static Result login() {
session("key", "example value");
return ok("Welcome!");
}
}
If there is no session cookie stored on client side this method will create new one and attach it to the HTTP response. Otherwise it will modify the existing one.
To read stored value use:
String value = session("key");
You can also remove value from the session:
session().remove("key");
or completely destroy it:
session().clear();
These are helper methods to work with the particular cookie witch in Play's terminology is called session. Nothing stops you from creating another cookie with similar purpose. But it'll require more writing. These helper methods saves your time and in many cases are more than enough.
You can specify session cookie name in your application.conf by setting session.cookieName property.
In play 2.8 the Http.Context was deprecated. This means, among other things, that the method "session()" is no longer available in a controller.
This is the updated way of doing it:
public Result info(Http.Request request) {
//This is the equivalent to the old session()
request.session() ...
}
The Http.Request needs to be passed down through the route defined in routes. More information here.
This question already has answers here:
How do servlets work? Instantiation, sessions, shared variables and multithreading
(8 answers)
Closed 5 years ago.
So far I understand Httpsession concepts in Java.
HttpSession ses = req.getSession(true);
will create a session object, according to the request.
setAttribute("String", object);
will, bind the 'String', and value with the Session object.
getAttribute("String");
will return an object associated with the string, specified.
What I am not able to understand is: I am creating a session object like
HttpSession ses = req.getSession(true);
and setting a name for it by calling setAttribute("String", object);.
Here, This code resides inside the server. For every person, when he tries to login the same code in the server will be executed. setAttribute("String", object); in this method the string value is a constant one. So, each session object created will be binded by the same string which I have provided. When I try to retrieve the string to validate his session or while logout action taken the getAttribute("String"); ll return the same constant string value(Am I right!!?? Actually I don't know, I'm just thinking of its logic of execution). Then, how can I be able to invalidate.
I saw this type of illustration in all of the tutorials on the WEB. Is it the actual way to set that attribute? Or, real application developers will give a variable in the "String" field to set it dynamically
(ie. session.setAttribut(userName, userName); //Setting the String Dynamically.. I dono is it right or not.)
And my final question is
WebContext ctx = WebContextFactory.get();
request = ctx.getHttpServletRequest();
What do the two lines above do? What will be stored in ctx & request?
HttpSession ses = req.getSession(true); will creates new session means. What value stored in ses.
Some [random] precisions:
You don't need login/logout mechanisms in order to have sessions.
In java servlets, HTTP sessions are tracked using two mechanisms, HTTP cookie (the most commonly used) or URL rewriting (to support browsers without cookies or with cookies disabled). Using only cookies is simple, you don't have to do anything special. For URL re-writing, you need to modify all URLs pointing back to your servlets/filters.
Each time you call request.getSession(true), the HttpRequest object will be inspected in order to find a session ID encoded either in a cookie OR/AND in the URL path parameter (what's following a semi-colon). If the session ID cannot be found, a new session will be created by the servlet container (i.e. the server).
The session ID is added to the response as a Cookie. If you want to support URL re-writing also, the links in your HTML documents should be modified using the response.encodeURL() method. Calling request.getSession(false) or simply request.getSession() will return null in the event the session ID is not found or the session ID refers to an invalid session.
There is a single HTTP session by visit, as Java session cookies are not stored permanently in the browser. So sessions object are not shared between clients. Each user has his own private session.
Sessions are destroyed automatically if not used for a given time. The time-out value can be configured in the web.xml file.
A given session can be explicitly invalidated using the invalidate() method.
When people are talking about JSESSIONID, they are referring to the standard name of the HTTP cookie used to do session-tracking in Java.
I suggest you read a tutorial on Java sessions. Each user gets a different HttpSession object, based on a JSESSIONID request/response parameter that the Java web server sends to the browser. So every user can have an attribute with the same name, and the value stored for this attribute will be different for all users.
Also, WebContextFactory and WebContext are DWR classes that provide an easy way to get the servlet parameters.
As I understand it, your concerns are about separation of the different users when storing things in the HttpSession.
The servlet container (for example Tomcat) takes care of this utilizing its JSESSIONID.
The story goes like this :
User first logs onto website.
Servlet container sets a COOKIE on
the user's browser, storing a UNIQUE
jsessionId.
Every time the user hits the
website, the JSESSIONID cookie is
sent back.
The servlet container uses this to
keep track of who is who.
Likewise, this is how it keeps track
of the separation of data. Every
user has their own bucket of
objects uniquely identified by the
JSESSIONID.
Hopefully that (at least partially) answers your question.
Cheers
Your basic servlet is going to look like
public class MyServlet{
public doGet(HttpServletRequest req, HttpServletResponse res){
//Parameter true:
// create session if one does not exist. session should never be null
//Parameter false:
// return null if there is no session, used on pages where you want to
// force a user to already have a session or be logged in
//only need to use one of the two getSession() options here.
//Just showing both for this test
HttpSession sess = req.getSession(true);
HttpSession sess2 = req.getSession(false);
//set an Attribute in the request. This can be used to pass new values
//to a forward or to a JSP
req.setAttribute("myVar", "Hello World");
}
}
There is no need to set any attribute names for your session that is already done. As others have suggested in other answers, use cookies or URL re-writing to store the sessionID for you.
When you are dealing with the DWR WebContext, it is simply doing the same thing as above, just normally the Request object isn't passed into the method, so you use the WebContext to get that request for you
public class DWRClass {
public doSomething(){
WebContext ctx = WebContextFactory.get();
HttpServletRequest req = ctx.getHttpServletRequest();
HttpSession sess = req.getSession(); //no parameter is the same as passing true
//Lets set another attribute for a forward or JSP to use
ArrayList<Boolean> flags = new ArrayList<Boolean>();
req.setAttribute("listOfNames", flags);
}
}
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.