I've got a memory problem in my application because of AJAX4JSF high memory consumption. So we have decided to set the NUMBER_OF_VIEWS_IN_SESSION to 1 and compromise the back button functionality.
However, after adding the following to the web.xml file, the back button still works.
<context-param>
<param-name>org.apache.myfaces.NUMBER_OF_VIEWS_IN_SESSION</param-name>
<param-value>1</param-value>
</context-param>
I would like to understand: How the back button still works?!! I've read that setting the NUMBER_OF_VIEWS_IN_SESSION to 1 looses the browser back button functionality.
Thanks in advance for your help.
I've read that setting the NUMBER_OF_VIEWS_IN_SESSION to 1 loses the browser back button functionality.
Either that article you're reading is babbling nonsense or you've misinterpreted the article. The back button's functionality can in no way be controlled from the server side on.
Perhaps the article meant the fact that you cannot submit the page which is been served from the browser cache by back button anymore because this would result in a ViewExpiredException. You'd need to create a Filter which adds response header to instruct the browser to not cache the page so that pressing the back button would fire a brand new GET request on the page so that you won't get a ViewExpiredException anymore when submitting a form on that page.
As to the high memory consumption, I suspect that your problem is caused by something else. Perhaps you're just cobbling too many data in a view or session scoped bean. Read this thoroughly: Why JSF saves the state of UI components on server? Last, but not least, run a profiler before making assumptions.
Related
We have this XPages application that has one master page (say M.xsp) and several sub-pages, all in separate iframes on the master page (loaded as A.xsp, B.xsp and C.xsp in separate tabs). The application runs fine, generally speaking. Each sub-page shouldn't interfere with the other pages, and as far as I know, it doesn't. Some page-dependent data is stored in viewScope variables, but for the most important parts we developed Managed Beans, with their data mostly in view-scope too.
Now, what we see is the following:
on page A, we do several clicks and some AJAX calls occur to fetch data from the server
we switch to page B, we do 3 AJAX requests for data to the server
we switch back to page A, we do one click to fetch some data again, and a beforePageLoad event occurs! Needless to say, the page is still loaded.
on the same page A, we do a new click to fetch different data, and beforePageLoad is triggered again!
viewScope is lost, my page-dependent bean is lost, very strange.
We checked, but changing the amount of memory dedicated to XPages didn't change anything.
XPages 9.0.1, browser-only.
Can someone please explain this behaviour: how come beforePageLoad is repeatedly executed? How can we prevent it?
Thanks!!
Twas indeed related to the max number of pages in memory. Every time an item in a list on page B was clicked, a sub-page (B1) was loaded in yet another iframe, using a URL with the item as parameter. Many clicks in the list forced many pages to load, causing all other pages disappear from memory. So when we moved back to page A and triggered some partial refresh there, it was as if the the page was new to the runtime environment.
I rewrote the sub-page B2 to stay in memory, and do a partial refresh itself when the list value changes. Quite a lot faster, and no unnecessary page drops.
I need to leave cache enabled and disable the user from seeing the information once they go back after logging out.
I'm aware that cached pages showing upon logout + back button is by design within browsers. I'm aware that disabling cache is a way to force logout + back to force a revalidation.
With JSP (CQ5 specifically), is this even possible?
I have the following solutions in mind, but am not sure which is the best approach for my needs:
Disable cache everywhere. This works, but is unacceptable because the publisher we are using will be too busy re-upping pages.
"Logout" button POSTs to Page A. Page A kills the session and forwards the user to Page B with some "You have been logged out" message. "Back" from Page B will pop the message browsers provide about having to re-post values. Yes = they log back out (harmless at this point) and get forwarded to Page B again. No = they sit at Page A harmlessly. But, "back" + "no" + "back" may land them on the cached page, or a selection from history would still show a cached page.
"Logout" button pops a new window, asking if they're sure/warning them to close their session. "I'm sure" does a window.opener.reload() or window.opener.close(). But, if JavaScript is disabled, we're doomed.
"Logout" posts to the current page. All pages check the existence of some POSTd value. If present, forward to Page B with a "you have been logged out message". Similar to #2. This will essentially re-cache the page into a "You have been logged out" page, but "Back back" or history will still have cached pages.
Is there some way to manually clear a user's cache, or force the validation check to happen even on cached pages? I'm out of ideas here...
Your problem here is that you are trying to cache something that should be kept secret. Caching information behind a password is not secure and is a risk.
However, it may make sense to cache the generic html parts of a page behind a password. Anything that any logged in user can see is OK in this regard. It is only the specific information such as username, address, phone number etc that is sensitive.
If you make a separate JSON call to pull down the data, the infomration will be lightweight, but still secure, as it is not cached on the system, but also not padded with html formatting etc.
The page can also have the intelligence to display a log in challenge if the users session has been interrupted for whatever reason, they retype and continue from where they left off, whilst still keeping the back button in place.
I would also think if there is any sensitive information is kept in the history, such as id's, actions etc, that can be a problem as well.
Just a few things to consider.
I am developing a spring MVC application. I ran into some interesting case.
To make it easier to explain i am taking the stackover flow buttons on the top as example( i mean those questions, tags, users, badges, unanswered buttons).
Now in my app i have similar buttons. when user clicks on any button it makes ajax call by passing proper arguments. Server makes sql queries and returns the results back.
Now assume that there is a crazy user like me who keeps on clicking those buttons without break. So each click is making a ajax call. And which ever completes its operation is showing up on front end. So even if the user clicks Tags button in the last it may show up and again the previous click on questions which took long time to return to front end can overwrite the page. How can i fix that? ( i want the tags data to be shown as it is the users last click)
In the first place i know that when user first clicks on question and then on tag i no longer need to query sql for questions button. Is there some way for me to stop processing the sql query for questions button.
Thanks
The best way to handle this is through the user interface - if the user takes some action (clicking an image) that will require significant processing on the backend, your UI should prevent other actions on the page from sending further messages to the backend until the original request is complete.
Ways to tackle this visually would be to disable/gray out other elements, make it obvious that some work is going on (with spinners, progress bars), etc.
On the server side, since each HTTP request is independent it would be cumbersome and difficult to add logic on the server to be able to detect if the user making this current request has another ongoing request currently being processed.
You probably need to take help of cookies. When the first time the action is done, write some cookie. Every time, check that cookie before you process.
You cannot simply disable a link or button from the UI and hope the user cannot do it. It can always be done in multiple ways. Additional checking is must.
(I haven't read your post completely. But from what I understand from the 1st answer...)
I had a similar problem, and I tackled it this way.
I did hand-coded ajax calls (as opposed to jQuery etc.)
I had a single global XMLHTTPRequest.
var xhr = new XMLHTTPRequest();
When the user clicked something, which needed an ajax call, I aborted the previous call, if already running.
if( xhr.readystate !=0 || xhr.readystate !=4 )
xhr.abort();
Then create a new instance of XHR, and do your business.
xhr = new XMLHTTPRequest();
xhr.open("GET", myUrl, true);
//attach callback function etc and do the send
If user refresh the page continuously using F5 functional key then the page loading is very slow and can be seen blank page for long time.
How to solve this problem?
I tried using cache on server side but I don't think that I am using it in proper way.
Can somebody help me with an example.
I think you need to use browser cache, which can be controlled by http headers, or meta tags.
http://www.mnot.net/cache_docs/
You need to set page cache to be around 5 seconds or some similar value so that no new request will be sent to server in that time interval.
A few things:
You could try to minimize processing time within your application, maybe by minimizing wasteful operations. Sounds like your application spends a lot of time recreating the output.
You could try to add some sort of caching on the server side, and and send the user the same page (ie no "new" processing) for some time. Depending on the mechanism, this may not be feasible though (https, security?). At least, afaik.
Of course you could change the way the site works. You could use Ajax to push information to the site the user is on, and so take the urge to refresh away from him.
And maybe your server just does not have enough power to serve a lot of users at the same time?
It is very difficult to stop user from pressing F5.
Try making your code more optimized.
Use meta tags for cache like:
cache-control
EXPIRES
PRAGMA NO-CACHE
Also check this for JSP caching.
response.setIntHeader("Refresh",5);
just use this jsp method for autorefreeshing of ur webpage...
http://www.tutorialspoint.com/jsp/jsp_auto_refresh.htm
Here is the thing : my webapp has loads of popups and my boss wants 'em closed on session expiry, coz when session expires and an user presses refresh on a popup, he is being shown the logon page -> user logs on -> user is directed to the dashboard. Now, a dashboard screen in a popup is totally uncool. Here is where google got me:
Have javascript to close popup onload. Generate this onload script into the response if session has expired (checking session expiry from jsp and including onload script conditionally).
Do you think this is a good way to it? What is the best practice for this scenario?
P.S: I am not allowed to use AJAX
In a past life, I made a popup manager object that maintained what windows were open. You should probably make one of these if not already done. Then, you can use setTimeout to call a function after so many minutes (or whatever time you want) have gone by. This will check for recent activity (probably via AJAX) and close the popup if you determine that the session has expired. If not, call setTimeout again with your new time, properly adjusted for most recent activity.
^^before the AJAX edit.
Well, since you can't use AJAX, can you put something in the url that will tell you it's a popup? Then you'll know not to show the login screen when the user hits reload.
The best way would be an XMLHTTP request to check login and close them if required - do this periodically.
Astute readers (meaning everyone) will notice that this is an AJAX request, but if you phrase it that way it might get accepted as whoever dictated that you 'aren't allowed to use AJAX' is clearly an idiot.
An alternative way to implement modal dialogs in a web application is to:
Model the dialog in a DIV, default styled to display: none;
On desired action, inject/append the Modal dialog DIV into the page source
Reset the CSS display so the modal dialog DIV is visible, overlaid on top of the page by setting the CSS z-index property
Make the modal dialog disappear upon either successful execution or the user cancelling out
Because the modal dialog is part of the page source, the dialog will disappear when the session times out. This approach doesn't spawn supporting windows that can be orphaned as the poster is attempting to address. And it fits the requirement of not using AJAX.
You can code these by hand, but I don't really recommend it because of having to support various browser. I suggest looking at the Yahoo User Interface. You can tailor it to suit your needs (IE: only modal dialogs), and it would support AJAX if requirements change down the road.
Beware of spawning modal dialogs from modal dialogs.
If your boss is asking you to achieve this, without using AJAX, then you're in trouble. He should understand that the only connection a browser has to the server (without refreshing the page) is javascript (what he understands to be ajax).
The best way to do this is to setup a script on the pages to ask the server if the user is still logged in every 30 seconds or so.
setInterval(function(){
$.get("loggedin.php", function(result) {
if (!result.isLoggedIn)
window.close();
});
}, 30000);
This script assumes you're using the jQuery framework for rapid development of javascript solutions. This also uses JSON (Javascript Object-notation) to test a return-value from the loggedin.php file.
Bottom line, you need to use AJAX. Tell your boss there is no other way. If he still doesn't get it, ask him to balance his checkbook without using math.
In theory, you could avoid AJAX by using a hidden flash widget...
But more practically, AJAX is the 'right' solution, and I think you will have to talk to your boss, determine where this 'no AJAX' rule came from, and convince him that AJAX is the best way to solve this problem.
Does he think AJAX would be take too much time to implement? If so, you should prove him wrong. Does he think it will be hard to maintain? If so, show how simple the code to do this will be, and how widely used the common AJAX libraries are. If your boss is reasonable, then his goal is to what is best for the product, and you should be able to reason with him.