AFAIK in JSF ViewState is stored into JVM memory when javax.faces.STATE_SAVING_METHOD is set to "server".
Is there any way to configure / setup a custom saving method that, for example, can use some (eventually, disk backed) storage engine (ie. memcache / redis) to store ViewState ?
Something like the equivalent of a custom session.save_handler in PHP.
is stored into JVM memory
To be more precise, it's stored in the HTTP session which is in turn managed by the container.
So, if you want to customize session management, then just do it at the servletcontainer level. It's unclear which one you're using, but in case of for example Tomcat, refer the Manager Component document under the chapters "Persistent Manager" for session storage on disk.
Related
I'm wondering why there is no single notice about the importance of immutability property when storing serializable objects in the HTTP session? I tried to check the JSF and Servlet API specifications but couldn't find anything related.
I've seen a specific problem in the case of JSF based clustered application where #SessionScoped managed bean is mutable i.e. user-modified parameter is stored as a field of this managed bean.
Trouble begins when the node "owning" the session (thanks to stickiness requirement in servlet API specs) dies and different node starts to take over serving the session, the latest state is lost. In fact, only the initial state is replicated. I believe this is because managed beans are placed in session (and replicated to backup nodes) only when they are created for the first time, at least this is confirmed by my tests performed on Websphere.
While one can debate whether this is a good design or not, JSF and even Servlet API still allows it to happen.
I also found some note in Oracle docs:
As a general rule, all session attributes should be treated as immutable objects if possible. This ensures that developers are consciously aware when they change attributes. With mutable objects, modifying attributes often requires two steps: modifying the state of the attribute object, and then manually updating the session with the modified attribute object by calling javax.servlet.http.HttpSession.setAttribute(). This means that your application should always call setAttribute() if the attribute value has been changed, otherwise, the modified attribute value will not replicate to the backup server.
Apart from manually updating the attribute as described above, is there any clean solution, preferably in an idiomatic JSF way?
In WebSphere Liberty, there is a property called
writeContents = "GET_AND_SET_ATTRIBUTES"
for the mutable session objects. For details, please see:
https://github.com/OpenLiberty/open-liberty/issues/2802
https://www.ibm.com/support/knowledgecenter/en/SSEQTP_liberty/com.ibm.websphere.liberty.autogen.nd.doc/ae/rwlp_config_httpSessionCache.html
Same property apply for database persistence.
Regardless of a language and framework, how does this work in a low level -- putting a variable into a session to authentication a user?
put_session(curr_connection, :current_user, user.id)
Does user user saved in a cookie? On a client? Then what prevents a user of a browser change it by storing id of any user they desire and get authenticated on behalf on that user? Or does user.id get saved on a server and on a client we have only a loooooong session id, in a cookie or in url?
The short answer is it depends. All languages / frameworks have their defaults, Ruby on Rails for example stores it in a cookie by default, PHP stores it on the server, etc. But in pretty much all of these languages, you can change your cookie store to whatever you want.
Some options (there may be more):
Cookies - In this case the cookie is encrypted before sent to the client. The key used for encryption is some sort of an application setting. This is somewhat secure, because even if session values are stored on the client, a user still cannot see or modify them, because he does not have the application key. The advantage of this is that it's very simple and requires zero setup, disadvantages include this being less secure than other solutions, and also the amount of data that can be stored in a cookie is limited.
Server memory - In this case, a cryptographically random session id is sent to the client, all session data is stored in the application server memory, identified by the session id. The advantage is that it's not written to disk and also not sent to the client. Disadvantages include the session data being lost when the application server is restarted.
Server Filesystem - The traditional approach (kind of), session data is stored in files so that it's persisted across application server restarts. In this case, access control to these files is key, but usually taken care of by the language or framework.
Server SQL Database - The traditional heavy-weight approach, all session data is stored in a relational database on either the application server or a separate database server. The advantage is that you have direct control to session contents of any suer, not just the logged on one (for example it's easy to do forced logout for an admin by removing session entries from the database). This same thing can also be a disadvantage in case of an application level attack. Also operation is more expensive.
Server NoSQL Database - About the same as a relational database, but a non-relational database like Redis can also be used. One drawback can be that access control in Redis is not very strong to say the least.
Session Service - In some enterprise applications you may want to implement some kind of a session service (RESTful or else). Obviously this just pushes the problem one layer back, session data must still be stored somewhere with one of the options above.
Your language or environment probably already supports some of these, and if you want one that is not supported out of the box, you can implement your own. However, session management is tricky business, it's quite easy to make it vulnerable. OWASP has a nice session management cheat sheet to consult.
Need to add global variable in REDIS Cache.
For Ex:
Consider an student, employee and Staff related application.
Every role has a unique object. When student log in to the application we need to get student information from redis. Same for other roles log in too.
If we store all the details at time of application initialization, we no need to send request to get role related details. If we store it into session, that data will be checking by every users login. And also session id has been varied for every users.
Is it possible?
If yes, How can we store the values at the time of application initialization?
First of all, since Redis is a cache, you are storing objects that may be evicted with time. When Redis becomes full, it will start clearing objects according to your eviction policy configuration.
Probably caching everything upon initialization is not the best course of action, I'd go with caching the objects when they are first requested, if they don't exist on Redis, store them for future retrievals. This way, if your Redis instance clears that object, your application logic will always find it (from cache or from local storage). That's called a Cache-Aside Pattern.
Your initialization logic varies depending on which technology / platform are you using.
ASP.NET MVC 5 or lower has the Global.asax file, ASP.NET 5 MVC6 has the Startup.cs file.
I wanted to understand impact of 'javax.faces.PROJECT_STAGE' property for a JSF application. A nice use case was presented in below links
https://dzone.com/articles/jsf-20-new-feature-preview-ser
http://www.java-tutorial.ch/java-server-faces/jsf-project-stage
Except presenting validation error messages, is there any other use case where this property really helps? I understand that we can check this variable to identify the environment and change certain functionality, however is there anything else that JSF does automatically to help developers? Would be great if you can share the experiences from your project?
Setting this param to Development enables better error messages, including in the client-side JavaScript, at the cost of some performance.
While setting this param to Production will turn off some error messages, and emphasize performance.
Source:
JSF 2.0 Reminder: Project Stage
According to the comment by wutzebaer for this linked post the javax.faces.PROJECT_STAGE property may control whether or not certain features are enabled (such as resource caching).
When we setting the PROJECT_STAGE as production we will get better error message, for example when we missed h:form tag around input fields then we may get following error message when stage is set as Development and when the stage is set as Production (or any value other than Development) we won't get any error message.
The form component needs to have a UIForm in its ancestry. Suggestion:
enclose the necessary components within <h:form>
Cache Busting for Resources during development
By resources, I refer to static resources such as stylesheets, javascript libraries, logo's and pictograms, etc.
By default, resources are loaded without any cache expiration (expires at max age or something). This is so, because resources are assumed to be static, in that they do not change during the lifespan of the Servlet Container. We benefit that way from caching those resources on the Client Side (Web Browser caching).
However, when releasing a new version of a library that might wrap a group of resources, we do not want users to get stuck with the old version of a resource. Typically Implementations, and as per the spec, resources will get automatically suffixed with the library name and version as query attributes. A typical resource will automatically be output as something like:
<link type="text/css" rel="stylesheet" href="/nqp-web/javax.faces.resource/components.css.xhtml?ln=primefaces&v=6.2">
This is handled by using a specific implementation of Resource.
So as you release new versions of a library, your users wont get stuck with old versions of resources in their cache.
However during development work, the version does not increase, but you still want the cache to expire, preferably immediately.
The default implementation is usually to make sure that based on the value of javax.faces.PROJECT_STAGE, specifically being DEVELOPMENT, the expire is set to immediate. You can see that in Mojarra's ResourceImpl for example:
long expiresTime;
if (FacesContext.getCurrentInstance().isProjectStage(Development)) {
expiresTime = new Date().getTime();
} else {
expiresTime = new Date().getTime() + maxAge;
}
Logging
As #vrcca already mentioned, a quick search for usages of isProjectStage reveals that this mostly just turns on additional logging when set to DEVELOPMENT.
References
What is the JSF resource library for and how should it be used?
Mojarra Implementation: ResourceImpl
Custom Resource Handler
Another function of setting the PROJECT_STAGE as Development is that we will also be able to see our changes in .xhtml files without restarting the server.
I'm developing a java EE web app using JSF with a shopping cart style process, so I want to collect user input over a number of pages and then do something with it.
I was thinking to use an EJB 3 stateful session bean for this, but my research leads me to believe that a SFSB is not tied to a client's http session, so I would have to manually keep track of it via an httpSession, some side questions here . . .
1) Why is it called a session bean, as far as I can see it has nothing to do with a session, I could achieve the same by storing a pojo in a session.
2) What's the point of being able to inject it, if all I'm gonna be injecting' is a new instance of this SFSB then I might as well use a pojo?
So back to the main issue I see written all over that JSF is a presentation technology, so it should not be used for logic, but it seems the perfect option for collecting user input.
I can set a JSF session scoped bean as a managed property of all of my request beans which means it's injected into them, but unlike a SFSB the JSF managed session scoped bean is tied to the http session and so the same instance is always injected as long as the http session hasn't been invalidated.
So I have multiple tiers
1st tier) JSF managed request scoped beans that deal with presentation, 1 per page.
2nd tier) A JSF managed session scoped bean that has values set in it by the request beans.
3rd tier) A stateless session EJB who executes logic on the data in the JSF session scoped bean.
Why is this so bad?
Alternative option is to use a SFSB but then I have to inject it in my initial request bean and then store it in the http session and grab it back in each subsequent request bean - just seems messy.
Or I could just store everything in the session but this isn't ideal since it involves the use of literal keys and casting . etc .. etc which is error prone. . . and messy!
Any thoughts appreciated I feel like I'm fighting this technology rather than working with it.
Thanks
Why is it called a session bean, as far as I can see it has nothing to do with a session, I could achieve the same by storing a pojo in a session.
From the old J2EE 1.3 tutorial:
What Is a Session Bean?
A session bean represents a single
client inside the J2EE server. To
access an application that is deployed
on the server, the client invokes the
session bean's methods. The session
bean performs work for its client,
shielding the client from complexity
by executing business tasks inside the
server.
As its name suggests, a session bean
is similar to an interactive session.
A session bean is not shared--it may
have just one client, in the same way
that an interactive session may have
just one user. Like an interactive
session, a session bean is not
persistent. (That is, its data is not
saved to a database.) When the client
terminates, its session bean appears
to terminate and is no longer
associated with the client.
So it has to do with a "session". But session not necessarily means "HTTP session"
What's the point of being able to inject it, if all I'm gonna be injecting' is a new instance of this SFSB then I might as well use a pojo?
Well, first of all, you don't inject a SFSB in stateless component (injection in another SFSB would be ok), you have to do a lookup. Secondly, choosing between HTTP session and SFSB really depends on your application and your needs. From a pure theoretical point of view, the HTTP session should be used for presentation logic state (e.g. where you are in your multi page form) while the SFSB should be used for business logic state. This is nicely explained in the "old" HttpSession v.s. Stateful session beans thread on TSS which also has a nice example where SFSB would make sense:
You may want to use a stateful session
bean to track the state of a
particular transaction. i.e some one
buying a railway ticket.
The web Session tracks the state of
where the user is in the html page
flow. However, if the user then gained
access to the system through a
different channel e.g a wap phone, or
through a call centre you would still
want to know the state of the ticket
buying transaction.
But SFSB are not simple and if you don't have needs justifying their use, my practical advice would be to stick with the HTTP session (especially if all this is new to you). Just in case, see:
Stateless and Stateful Enterprise Java Beans
Stateful EJBs in web application?
So back to the main issue I see written all over that JSF is a presentation technology, so it should not be used for logic, but it seems the perfect option for collecting user input.
That's not business logic, that's presentation logic.
So I have multiple tiers (...)
No. You have probably a client tier, a presentation tier, a business tier, a data tier. What you're describing looks more like layers (not even sure). See:
Can anybody explain these words: Presentation Tier, Business Tier, Integration Tier in java EE with example?
Spring, Hibernate, Java EE in the 3 Tier architecture
Why is this so bad?
I don't know, I don't know what you're talking about :) But you should probably just gather the multi page form information into a SessionScoped bean and call a Stateless Session Bean (SLSB) at the end of the process.
1) Why is it called a session bean, as far as I can see it has nothing to do with a session, I could achieve the same by storing a pojo in a session.
Correction: an EJB session has nothing to do with a HTTP session. In EJB, roughly said, the client is the servlet container and the server is the EJB container (both running in a web/application server). In HTTP, the client is the webbrowser and the server is the web/application server.
Does it make more sense now?
2) What's the point of being able to inject it, if all I'm gonna be injecting' is a new instance of this SFSB then I might as well use a pojo?
Use EJB for transactional business tasks. Use a session scoped managed bean to store HTTP session specific data. Neither of both are POJO's by the way. Just Javabeans.
Why shouldn't I use a JSF SessionScoped bean for logic?
If you aren't taking benefit of transactional business tasks and the abstraction EJB provides around it, then just doing it in a simple JSF managed bean is indeed not a bad alternative. That's also the normal approach in basic JSF applications. The actions are however usually to be taken place in a request scoped managed bean wherein the session scoped one is been injected as a #ManagedProperty.
But since you're already using EJB, I'd question if there wasn't a specific reason for using EJB. If that's the business requirement from upper hand, then I'd just stick to it. At least, your session-confusion should now be cleared up.
Just in case you're not aware of this, and as a small contribution to the answers you have, you could indeed anotate a SFSB with #SessionScoped, and CDI will handle the life cycle of the EJB... This would tie an EJB to the Http Session that CDI manages. Just letting you know, because in your question you say:
but my research leads me to believe that a SFSB is not tied to a client's http session, so I would have to manually keep track of it via an httpSession, some side questions here . . .
Also, you could do what you suggest, but it depends on your requirements, until CDI beans get declarative transaction support or extended persistence contexts etc, you'll find yourself writing a lot of boilerplate code that would make your bean less clean. Of course you can also use frameworks like Seam (now moving to DeltaSpike) to enhance certain capabilities of your beans through their extensions.
So I'd say yes, at first glance you may feel it's not necessary to use a stateful EJB, but certain use cases may be better solve through them. If a user adds a product to his cart, and another user adds this same product later, but there is only one unit in stock, who gets it? the one who does the checkout faster? or the one who added it first? What if you want to access your entity manager to persist a kart in case the user decides to randomly close his browser or what if you have transactions that spawn multiple pages and you want every step to be synchronized to the db? (To keep a transaction open for so long is not advisable but maybe there could be a scenario where this is needed?) You could use SLSB but sometimes it's better and cleaner to use a SFSB..