anyone know if we can create a session-like mechanism in java desktop application?
i am going to develop a java desktop application which has a log-in mechanism to ensure only authorized people can access stored information, then i think if java can something like session, or if there is any mechanism to do something like session. that's all.
can somebody explain?
Basically a session consists of a set of binary or serialized objects, mapped to a session id. Either independently or, most likely, via a Map or Table. So yes, you can implement something like that, by using a smart DB schema. Just be careful about who can see (and use) that DB.
I think, though, your approach is not the best one. After all I think the app will be used by a single user at any time on each machine, so I don't think this is the best approach. Rather you should save the current "session" (AKA app state) in some way, instead of thinking of the session as in the Servlet way.
The session is just a hashmap that is singleton per user . So , you can think that every user has their own hashmap which allows them to store objects. In the servlet , the session is provided by the HttpSession interface.
The session-like mechanism depends on your application 's architecture .If it is a thick client implementation , which contains only 2 tiers (database tier and the java client) ,and most of the business codes are embedded inside the java application , then every user has their own JVM to run the java code on their machines .Thus , you simply create a singleton hashmap for your desktop application .When the application starts , just initialize this hashmap and put a key and its boolean value to indicate the login status of the user ( e.g. singltonHashmap.put ("LOGIN" , false)) .Once the user login , you should update the value of the LOGIN key to true to indicate that the user is logged in .
If the java desktop application is thin client implementation , which has an application server to process all the requests from all users, then you can use the stateful session bean defined by the Enterprise JavaBeans specification (EJB) .There is an one-to-one mapping between a client and a stateful session bean instance .The application server will makes sure that subsequent method invocations by the same client are handled by the same stateful bean instance . You just declare a hashmap inside an stateful session beans and put the objects that you want to keep track during the conversation in that hashmap. Here is an example for your reference.
Related
When I try to access Liferay Portal session data it seems as it doesn't contain data stored by internal Liferay Portal processes. Is it possible to access the token that was stored in the OpenId-Connect Login process?
Basically, I was tasked with finding Software, that can make implementing a Portal, which displays functionality offered by API-Endpoints of multiple different internal Platforms easier. Currently, I'm looking at Liferay Portal 7.2. For the Login, I've used the OpenId-Connect implementation of Liferay Portal since authentication is handled by an internal Login server. The access token returned at the end of the OpenID-connect login process is an API-Token which I then want to use to access various API-Endpoints.
Currently I get the Session like this
HttpSession httpSession = PortalUtil.getHttpServletRequest(actionRequest).getSession();
After looking at the OpenId-Connect implementation in
com.liferay.portal.security.sso.openid.connect.internal.OpenIdConnectServiceHandlerImpl
I then tried to get the Session Object like this.
Object openIdConnectSessionObject = httpSession.getAttribute("OPEN_ID_CONNECT_SESSION");
But at this point, openIdConnectSessionObject is always null. I have read that different scopes have different sessions, but is there a way to access this data or is Liferay Portal maybe not really fit for what I'm trying to do.
There's one detail worth noting:
PortalUtil.getHttpServletRequest(actionRequest) will give you access to an artificial PortletRequest object that adheres to the HttpServletRequest interface, in case you need that for some API that expects requests from the servlet, not the portal, world.
A PortletRequest contains only parameters (and session information) directed to a particular portlet, and nothing else.
If you're interested in the actual underlying HttpServletRequest, you'll need PortalUtil.getOriginalServletRequest, which takes an HttpServletRequest as input. And you'll get that the way you've already explored. In the end, you'll have
session = PortalUtil.getOriginalServletRequest(
PortalUtil.getHttpServletRequest(actionRequest)).getSession();
to get the actual server's session.
I've not checked if that is useful, or even an advisable solution to the problem you state, but it might bring you further along solving your problem.
When a user is interacting with a website, there's usually some object that could be considered the "current" object, like a shopping cart, or, to use an example in my world, a manufacturing job. What's the best practice for tracking that current object from page to page? I can think of a few:
put the ID as a request parameter (downside is security, since a
hacker could use that to change the URL to a different ID)
a session object (downside is if you have a huge amount of users
and/or the current object has a large memory footprint)
cookie? (Haven't tried that one)
Have I missed some obvious answer?
BTW, we're using Java, WebLogic and Struts1.
It really depends on your technology stack as to what "best practice" would be for you right now.
For example, if you're building a traditional Rails application using ERB templates without a MVC front end or anything, then I think that using the session object that the Rails framework provides for you would be best.
Most web frameworks will supply you an easy way to keep track of a particular user that's browsing the website. Most of the ones I've seen use a combination of your second and third options. They have a session ID that is stored as a cookie in the user's browser and every time that user sends a request to the web server, it loads a Session object from memory or the database using the session ID value that was stored in that cookie. Memory shouldn't be an issue unless you have an enormous number of users, but that also depends on the type of information that you're storing in there.
If you're storing entire database rows or records, and the sessions are being stored totally in memory, then maybe you should consider only storing the IDs to those records.
Research your particular web framework well to see how it handles user sessions.
As far as a cross-platform best practice, the Session object paradigm seems tot be the best approach to date. It permits matching of request parameters to tracking of sessions independent of the handling of the request parameter. An extension to this is that the Session object provides a handy place to put a collection of things for use if the session is re-identified (Java uses a Map).
Generally the Session is a representation of a single web browser visiting a single website repeatedly. Since there is nothing associating one request to another, this is generated synthetically from a combination of items, including user agent string, reply ip address, etc (in the past it was a stored value in a cookie, which caused no end to security issues).
Assuming you have a reliable Session object available, typically one stores the items that a supposed "single user" driving the session should have access to. So, if you have a shopping cart, it might be represented as a shopping cart object accessible from the session. In Java, that might be a map.
When identifying a new session
// request is a HttpServletRequest object in this example
if (request.getSession(false)) {
// must be a new one
Session newSession = request.getSession(true);
newSession.putValue("shoppingCart", new ShoppingCart());
}
Later on, when adding to the cart
ShoppingCart cart = (ShoppingCart)(request.getSession(false).getValue("shoppingCart"));
cart.addItem(item);
The benefits of separating out the detection from the request handling make it easy to fix / tweak session tracking without altering the code for the "session contents".
The other Answers are correct. Just a bit more explanation.
The Java Servlet technology’s Session object is indeed aimed at solving this exact problem, how to track a single user’s set of current objects over time, beyond the HTTP request-response lifecycle. This lends statefulness to an otherwise stateless protocol (HTTP). Every Servlet container (Tomcat, Jetty, WildFly, and so on) automatically handles the details such as using cookies or URL rewriting so you needn't worry about that.
Yes, as you add stuff to the Session object its memory usage grows in size. If running low on memory, your Servlet container such as Tomcat may choose to write an older Session object to storage using Serialization. The catch here is that all your objects in the Session must be serializable. Ensuring your classes (and all their nested objects) can correctly handle serialization can be a big chore.
Tip: If possible add memory to your server to more that handle your highest session load. As the wise man said, "Algorithms are for people who don’t know how to buy RAM.".
In our web application (in JBoss using Struts) we use sessions largely for security as well as to cache some data for a User. Thus, every user logged into the application has a session and different data cached in it.
Based on some parameter change, i want to change the cache of the subset of users who are logged in (i.e. have session)
Can this be achieved? I have not been able to find anything so far from general search.
You can use a HttpAttributeListener
a basic example here
HttpSessionAttributeListener:
The HttpSessionAttributeListener interface enables an object to
monitor changes to the attribute lists of sessions within a given Web
application. The HttpSessionAttributeListener in turn extends
java.util.EventListener. The methods in it are
attributeAdded(HttpSessionBindingEvent se)- This is the notification that an attribute has been added to a session.
attributeRemoved(HttpSessionBindingEvent se)- This is the notification that an attribute has been removed from a session.
attributeReplaced(HttpSessionBindingEvent se)- This is the notification that an attribute has been replaced in a session.
You can do it by storing each session object in a static List<Session> in some holder object. You can put it by a HttpSessionListener#sessionCreated(..). Remember to remove it from the list on sessionDestroyed(..)
Then, whenever you want to do something, simply loop the previously stored list of sessions and do whatever you want with them.
You have basically 2 options:
Push the changes. Get hold of all HttpSession instances in an application wide map which you manage with help of a HttpSessionListener. This way you can just get them from the application scope and walk through them to make the necessary changes directly.
Poll the changes. Store a change instruction in the application scope. On every HTTP request, check with help of a Filter or ServletRequestListener if a change is required, then make the necessary change in the current session and remove/disable the change instruction.
A completely different alternative is to use an application wide shared cache, such as Terracotta or Ehcache, so that you don't need to duplicate the same data over all HTTP sessions. You'd just need to deal with the data on a per-request basis. When database access comes into picture with JPA, then read on about "2nd level cache", that's exactly what it does.
When I send a data through a form, I use reusable component JavaBean to store the data and retrieve it using get property and pass that data where ever I need it in the application.
But if I restart the web server, whatever data I had passed to that JavaBean will be lost and again I need pass the data to that Java Bean. Is there anyway to pass the data to the JavaBean and store (set) it permanently, so that i can access it even in the case of server restart?
After you restart the server , the session of that client will be killed automatically, so you cannot hold the data in bean.
Java beans stays in the memory and particularly within some scope (i.e. request, session, application , etc..)
Now if you restart the app server it is definitely going to kill all scope and so the result.
if you want to persist data then use DBMS
There are many ways to persist the data across server restarts ( to a database, or a file for example ), but I find this scenario a little strange. What if two users set the same java bean? Who takes precedence? Or is the beans contents on a per user basis?
If you really want to save objects, then you have to look for non rational database systems. The database system 'Objectivity' is such a representantiv of that.
I've been always trying to avoid using Sessions. I've used spring security or other ways of having user logged in the application, which is I suppose the major use case for using Sessions.
But what are the other use cases ? Could you please make a list of those most important ones ? How come that I've been able to develop even complicated applications without using Sessions?
Is it because I'm using spring-mvc and using Sessions is practically not needed except the login stuff ?
EDIT: Guys this question was asking for use cases... Most of the answers explains what are sessions for. If we summarize some usecases, we can say for sure, when to use database or sessions for maintaining conversation state...
Don't you remember any concrete scenarios you needed sessions for? For past years :)
for instance some conversational state may become persistent after some point / event. In this case I'm using database from the beginning.
I think you can do anything you want without storing anything on a sessions.
I usually use the sessions to avoid having to pass state between the client and server (used id as an example) and when I don't want to send sensitive information to the client (even in encrypted form) as it might be a security problem.
Other ways of avoiding using the session are:
store some state on a database, e.g. shopping carts, instead of in the session, even if the cart is discarded after a certain amount of time.
store state in cookies e.g. for user customization
One use case when it's really useful to use the session is for conversations, although usually frameworks manage that behind scenes, and store the conversation in the session.
edit
Converstions (in my understanding) are something like wizards, in which you complete several forms in different pages and at the end you perform the action. e.g. in a checkout process, the user enters his name, shipping address and credit card details in different pages, but you want to submit the order just at the end, without storing any intermediate state in your DB.
By sensitive information I mean, imagine in the previous example, once the user sent his credit card details, you shouldn't return that information in any format (even encrypted) to the user. I know it's a bit paranoid, but that's security :).
In the ecommerce system i'm working on, there is an external system at the back-end which stores users' saved shipping and billing addresses. Our web app talks to it by making web service calls to retrieve those addresses. When we get the addresses, we store them in the session. That way, we only have to call the service once, when the user firsts looks at their addresses, and not every time we serve a page which needs address information. We have a time-to-live on the addresses, so if the addresses change (eg if the user telephones the customer service desk to change an address), we will eventually pick up the fresh ones.
It would be possible to store the addresses in our database, rather than in the session. But why would we? It's transient information which is already stored permanently somewhere else. The session is the ideal place for it.
Well in one sense your question is deep (what's SPECIAL about a session is worth knowing) and in another sense it's shallow (what can't I do if I don't use them turns out to be a somewhat odd question)
In the end a Session is merely (or could be) a ConcurrentHashMap (in fact it usually isn't that threadsafe) with a a key of unique session id passing as the cookie. You know why it's useful, but to answer you for use cases
clustering (this is how state gets distributed across nodes)
caching general state of the user and their objects (as opposed to reloading from db each time)
built in methods for sessionlisteners to watch when someone is timed out, or attributes change.
= used for by a lot of localization utilities
Can you do all this with a database or your own hashmap implementation/filter? Of course, there's nothing magical about Sessions. They are merely a convenient standard for having some objects follow a logged in user and be tied to the lifetime of that user's use of the application.
Why do you use Servlets? You could also implement your own socket level standard? The answer to that is using standard apis/implementations provides convenience and other libraries build upon them.
The cons are
you are reinventing the wheel and some code that has been time tested
you won't be able to use a lot of built in facilities for monitoring/managing/clustering/localizing etc.
Sessions are one way of maintaining conversational state across multiple requests (e.g. multiple stateless HTTP requests.)
There are other ways of implementing conversational state, for example, storing an authentication token or some suitable conversation id as a cookie and maintaining a store of conversation id to session state. (In essence, duplicating what the app server is doing when it provides sessions.)
That you haven't needed to use sessions means that your application either doesn't need conversational state or you've implemented it in a different way. For example, perhaps your application uses an authentication token (say a cookie) and persists all state changes to the database. With that kind of arrangement, there is no need for a conversation state.
Hi you can take an example of shopping cart because since Http is stateless protocol it does not maintain the status of the user who sends the request.
For e.g.
If one user sends a request to buy camera from say eBay and after some minutes another user sends a request to buy laptop.
But since http is stateless protocol so server is not able to separate the request send by the users and may it happen that the bill of the laptop may be given to first user.
So through session we can maintain a particular entity over the server side for a particular user.