Since I don't have in depth knowledge of spring session scope implementation.
Can anyone please tell me if it is wise to use Spring Session scoped beans, where HttpSession object is very crucial. Like a web application where thousands of users access the site simultaneously.
Is spring session scoped bean saved in HttpSession object?
Or even if HttpSession object only refers to the spring session scoped bean, are we not making session object heavy?
How is it different form storing any bean directly in HttpSession object (making HttpSession object heavy point of view)?
The object is not really stored in HTTP session. It is linked with session id and actually stored inside of the Spring context. A session listener is used to clean instances once session is closed. See SessionScope JavaDoc.
Here's what the Spring docs say:
Scopes a single bean definition to the lifecycle of a HTTP Session.
Only valid in the context of a web-aware Spring ApplicationContext.
"Heavy"? No heavier than the object you're putting in it. Sessions should have a finite lifetime. A few kbytes per session won't be the end of your application. A simple calculation for the number of simultaneous sessions and object memory requirements should reassure you about your app server memory settings. You can always increase min and max memory if needed.
Storing things in HTTP session happens the same whether you're a Spring bean or not. The bean factory just does some extra things to help manage the object lifecycle for you.
Is spring session scoped bean saved in HttpSession object?
If the HttpSession object you mentioned here is actually provided by spring-session (spring-session wraps the httpSession object in original httpRequest), the answer would be YES -> indeed, all the spring session scoped beans are saved in the httpSession provided by spring-session as attributes.
Or even if HttpSession object only refers to the spring session scoped bean, are we not making session object heavy?
No. The "heaviness" of the httpSession very much depends on the objects you put in. In addtion, session beans are meant to be ephemeral. Last but not least, the session object in micro-services world is usually offload to a stand-alone store, like Redis or HazelCast. So, it won't be considered as "heavy" in terms of memory consumption.
How is it different form storing any bean directly in HttpSession object (making HttpSession object heavy point of view)?
No difference at all (assuming you are using spring-sesion), as all the all the spring session scoped beans are saved in the httpSession provided by spring-session as attributes.
Related
Is there a way I can inject an object in a session scope into my resource classes? I want this object to be the same object for requests part of the same session (The Servlet container manages sessions for us, but internally Tomcat just sets a JSESSIONID cookie). I know I can use a Singleton scope, Request scope, and Per-lookup scope using their respective annotations. How can I get Jersey to store objects in session scope?
I am new to EJB so please don't mind anything silly in the question.
I have a doubt that someone might be able to solve hopefully.
I have the following Stateful Bean:
#Stateful
public class SessionBean implements SessionBeanRemote {
private int count = 0;
#Override
public int getCount(){
count++;
return count;
}
}
And this is the client that invokes the Bean (Servlet)
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
InitialContext ctx;
HttpSession session = null;
SessionBeanRemote obj;
try {
if (session.getAttribute("myBean") == null) {
ctx = new InitialContext();
obj = (SessionBeanRemote) ctx.lookup("SessionBean/remote");
session.setAttribute("myBean", obj);
} else {
obj = (SessionBeanRemote) session.getAttribute("myBean");
}
System.out.println(obj.getCount());
} catch (NamingException ex) {
Logger.getLogger(TestServlet.class.getName()).log(Level.SEVERE, null, ex);
}
}
Now I was wondering if it is ultimately HttpSession that has to hold the session bean then why use EJB at all, why not just store whatever we want to in the session directly rather than having it in the session bean first and then storing that bean in the session.
And also I was wondering if lets say I change my #Stateful annotation to #Stateless and then execute the same code on the client side and store the bean in the session then also I can extract the same bean from the session then what is the difference between stateless and stateful, I know that when new lookup is done there is a chance that same stateless bean might be returned to me where as with stateful bean it is always new when we do a lookup. But is that it?
P.S. As I mentioned earlier, I am new to EJB and all the doubts are based on what I have understood from a few tutorials online and some questions on SO. I have also tried running it locally but unfortunately I am not able to deploy the application on the GlassFish because of following error "Exception while loading the app : EJB Container initialization error". I am trying to look into it.
They're two unrelated concepts.
If you seperate concerns, and you should. Then the HTTP session and EJB session(s) operate at logically distinct layers. The http session is for holding an individual web browser and user's state. An EJB session is used for holding transactional, scalable and fault-tolerant and "transparently" (and possibly remote) reference(s) within the context of an Enterprise application client.
The fact that you're using EJB(s) to serve web content, does not mean you cannot also use those same EJB(s) to serve JFC/Swing (or JavaFX) clients.
I'll try to give you a simplified answer.
Yes, you have to store reference to the SFSB somewhere, in case of web application in http session, but as Elliott wrote you may have different client types also.
Some benefits of Session bean vs POJO:
container transaction management
container security enforcement
possible remote access via remote interface
allows to be deployed as separate module (EJB) for potentially better reusability.
If your session bean relies on state, then it is more logical to hold the state in the bean rather than pass all state info in each method call.
Your example is extremely simple, you don't use transactions, persistence, security, so there is no point of using SFSB or even EJB at all.
SFSB are considered to be rather heavyweight, in general should rather be avoided and I'd say majority of web applications don't use them (depends on application requirements really). So you should design your services to be stateless and rather use stateless beans than stateful, then you will have better performance and easier reusability.
So if you plan to use some of the features I provided, you may benefit from EJBs, otherwise you maybe happy with just Http session and business logic in POJOs.
EJB Sessions
A session in EJB is maintained using the SessionBeans over the server's JVM. You design beans that can contain business logic or calculations or dynamic pages, and that can be used by the clients. You have two different session beans: Stateful and Stateless.
Stateful: is somehow connected with a single client (each bean's object). It maintains the state for that client, can be used only by that client and when the client "dies" then the session bean is "lost". Stateful bean's life-cycle is bind with the client. (very useful in role-based applications/systems)
Stateless: A Stateless Session Bean doesn't maintain any state and there is no guarantee that the same client will use the same stateless bean, even for two calls one after the other. The lifecycle of a Stateless Session EJB is slightly different from the one of a Stateful Session EJB. Is EJB Container's responsability to take care of knowing exactly how to track each session and redirect the request from a client to the correct instance of a Session Bean and to same job for every one.
Where:
HTTPSession: It is acquired through the request object. You cannot really instantiate a new HttpSession object, and it doesn't contains any business logic or calculation, but is more of a place where to store objects (for client as output or server as input), and for communication of two or more system over the network.
Is there any advantages of using SessionMap over Map for a session in web application ?
1 advantage I found was you can invalidate a SessionMap but not Map.
The SessionMap is specifically designed for the purposes if you want to have access to the servlet session attributes. So, the user is able to keep a synchronized collection of objects in session and use it instead of HttpSession directly.
This object is automatically injected by the servletConfig interceptor which is a part of the defaultStack if you implement SessionAware interface in the action class.
As soon as you don't need to work with servlet session directly and don't have access to it you can at least invalidate a session that finalizes the collection of objects in it.
A new session map required to action context if you want to continue to use a session.
It seems to me that "session" scope is another means to keep objects in session as
using setAttrubute / getAttribute
Correct?
You know, dont know why, it does not work for me.
<bean id="sabreUser" class="util.MyUser" factory-method="getSomeUser" scope="session">
<const args...>
What I see is that after the initialization and initial deploy the MyUser properties are correct.
Then, in the first session I change MyUser property, the session is closed.
The second session runs and it sees the last set value from the previous session!
What does that mean?
I expect this object to be initialized whenever a new session starts. But it better looks as singleton, though you see - "session" attribute is set.
I can see the cause of the problem in that a Servlet's fields is initialized with #Autowired
so, once it is initialized, every other session will see its fields set and does not "ReWire" this properties. It happens once? How to overcome this problem?
The Spring session does not exactly match the HttpSession, and even the Spring documentation on the #SessionAttributes annotation says that it might be stored in the session or "some conversational storage". I got that from The Spring docs for 2.5
I've basically quit trying to make sense of it, and just got on with my life, if I want something stored in the HttpSession, I just have Spring inject the HttpSession to me, assuming you're using Spring MVC its pretty easy, instructions on the same page.
Session-scoped beans are beans that live throughout the http session. They are stored in the session via setAttribute in some way.
So - yes.
Session scoped beans are stored in Http Session by Spring framework. This scope is valid only in the context of Web application.It also works for Portlet envionments . When using in Portlet environment, there are two notions of session, application scope and portlet scope (default).
I'm maintaining a Java web application.
Looking into the login code it gets an HttpSession out of HttpServletRequest via the getSession() method of HttpServletRequest. (It uses some values in the session for authentication purposes)
However I'm worried about session fixation attacks so after I have used the initial session I want to either start a new session or change the session id. Is this possible?
The Servlet 3.0 API doesn't allow you to change the session id on an existing session. Typically, to protect against session fixation, you'll want to just create a new one and invalidate the old one as well.
You can invalidate a session like this
request.getSession(false).invalidate();
and then create a new session with
getSession(true) (getSession() should work too)
Obviously, if you have an data in the session that you want to persist, you'll need to copy it from the first session to the second session.
Note, for session fixation protection, it's commonly considered okay to just do this on the authentication request. But a higher level of security involves a tossing the old session and making a new session for each and every request.
Since Java EE 7 and Servlet API 3.1 (Tomcat 8) you can use HttpServletRequest.changeSessionId() to achieve such behaviour. There is also a listener HttpSessionIdListener which will be invoked after each change.