I'm performing a validation task that takes a while and am spinning the validation process into a separate thread. I've got the progress bar side of things working, with PortableRenderer and a ViewScope allowing it to update the progress bar component.
However, I'm trying to redirect the user once the page either finishes or a error in validation occurs, without the need of user interaction.
I'm using AND new to icefaces2.0(beta 1) and JSF 2.0, so the answer might be right in front of me. Sorry if this is a pretty simple question.
Have ajax to execute this job rather than spawning a thread yourself.
Update as per the comments: well, that was a bit curt. But spawning a thread yourself inside a servletcontainer is recipe for major trouble if you don't know what you're doing. The functional requirement makes now a bit more sense. Your best bet is using IceFaces' push or poll component which in turn causes JavaScript in the client side to do a window.location on the desired URL.
I eventually fell back to my own way of doing it.
I'm putting the JSF bean into a session attribute with a portable renderer injected as a property. The session attribute is used since Spring cannot get the "View" scope. If there is a way for Spring to do so, that saves a lot of potential pitfalls, but alas I do not know how.
Once the page loads, a jquery AJAX call is made to a Spring Controller, which gets the JSF bean out of the session, removing it in the process, and proceeds to "validate it". As it proceeds, it sticks the current completion status into a session attribute and calls the bean function that invokes the portable renderer, which in turn updates the progress meter.
Also part of the page load function, is a separate function that calls another Spring Controller, which returns the completed status object, which may/may not have error messages.
I plan to remove the second controller by just checking values already on the page that get rendered by the portable renderer and publishing all those errors into the bean, which can then be rendered easily and dependably.
This way, as BalusC said, removes the creation of threads not directly spawned by the container and allows me to redirect automatically via window.location on successful completion.
If there is a better way to do this, which I imagine there is, please do add an answer. My knowledge with Icefaces and JSF is severely lacking currently and I'd thank anyone with the best way to do this.
Related
I could do with some help once again...
We built our own forms in XPages. Forms are defined by a user in Notes, and they are used through XPages/web. We added several managed beans to get more grip on the data used by the page and controls that are on it. The whole thing is heavily nested, the form control can be used more than once on a page, repeat controls are used as well, and now I need to partially refresh a panel.
Some of the code:
<xp:panel id="ccAnyForm">
<xp:this.dataContexts>
<xp:dataContext var="formulaire">
<xp:this.value><![CDATA[#{javascript:compositeData.formName || compositeData.dataSource.getItemValueString("Formulaire")}]]></xp:this.value>
</xp:dataContext>
<xp:dataContext var="formdata">
<xp:this.value><![CDATA[#{javascript:PageData.getForm(formulaire, compositeData.dataSource)}]]></xp:this.value>
</xp:dataContext>
</xp:this.dataContexts>
<xp:panel id="aFormulaire${javascript:compositeData.name}">
<xe:switchFacet id="switchFacet1">
<xe:this.selectedFacet><![CDATA[#{javascript:formdata.isTabbed()? "tabbed": "flat"}]]></xe:this.selectedFacet>
PageData is a Java bean, and I lose formdata when doing a partial refresh. If I set partial execution mode in the EventHandler (data validation is disabled), I get the error that says formdata not found on the last line of the snippet. If I clear partial execution mode, I get nothing at all: no error, no Java error, no SSJS error, nothing.
It must be my lack of understanding the life-cycle of objects and variables, for I prbably have to use ValueBindings or so, but I don't know how.
Help...
I've seen dataContexts recalculate as null, particularly when dependent on other dataContexts. I think in Apply Request Values phase. When I had that I changed the code to only calculate in Render Response phase.
However, I don't think that work for you, because the Switch control will need the value before Render Response, and there's no easy way to get hold of which other phase is running.
The approach I'd take is to have a property in your bean (e.g. showTabbed) that holds which Switch facet to show. Call a bean method to set that property on page load. Then in your partial refresh, call the method again, checking whether the Formulaire field has changed to determine whether or not to call setShowTabbed(boolean) again. That will minimise the number of calls even more and should prevent the problem.
I have a Spring MVC application where I sometimes have to add a new object to a list, and at some point, save the page. At every point where I need to add something to a list, a controller action is called and when it is done adding it returns the page. The state of the page then is lost. (ie. scrollbar position). I would like to preserve the page state, also after saving the page (which does a redirect to the new page)
Right now I am putting some variables in the session, and reading them out EVERY time. I find this quite ugly.
Does anyone know like a solution to this? Or any third party dependency which can make my life easier on this? :)
Thanks in advance.
Ps. I hope my question is clear, and not too abstract. If so, I will try to clarify it more.
One way to avoid the complete page refresh is to use ajax. Submit the new List item via an ajax request and the browser will not perform the full refresh.
Exists another variant. You may perform AJAX call to Controller method and send only the data you need to save. After that through #ResponseBody annotation you can return refreshed data or any other result. So this solution force you to use AJAX call. You may use JQuery for this purpose.
Is there a quite easy way to implement progress bars in JSP. Basically I have a JSP page that goes to a servlet that calls up a method, now this process is going to run for a long time and I want to indicate the status of the progress just like the progress bar that shows up in the eclipse taskbar when we execute any java program.
I have found a nice tutorial here http://onjava.com/pub/a/onjava/2003/06/11/jsp_progressbars.html but it seems little outdated.
Are there any new and easy ways to implement this?
Determining the progress of a particular task is a surprisingly complicated thing once you get into the details. How do you determine for example that you are 50% done? And what happens if the last 10% of your task takes 1/2 the total time?
Usually for a web app, if you do want progress bars, then going the AJAX route is best, as some of the posters mentioned above.
I find, however, that on the web, it is suitable to indicate to the user the something is happening. Just have a spinner of some sort made visible when the page is submitted, and then hidden again when it is rendered (see here). This is very easy to do, causes no additional performance hit, and is indicative of some sort of progress
There is a lot of solutions for example jQuery.
You can use Jquery with Ajax to update progress bar:
http://jqueryui.com/demos/progressbar/
In my opinion, when you call your jsp, it should return to the user immediately but also indicate that some complex task is being dealt with in the background (with a loading spinner, for example). If you want to know the task's progress, you should use either Ajax polling, or Comet push in order to retrieve it from your server. For just getting and displaying progress, I think Ajax is sufficient and Comet might be a bit of an overkill. Here is more on the Ajax approach:
http://en.wikipedia.org/wiki/Ajax_(programming)
More on your question, a servlet(and also a jsp) work according to the HTTP protocol, which is based on the request->response model. In today's world, there are rarely sites where you go to a jsp to do a complex task and then you have to sit around doing nothing while your request is complete. You might want to give your user the freedom to still interact with your web-application/website while his request is being dealt with in the background.
I have a Java web application which stores some data in the session. The data in the session changes as the user interacts with the application (e.g. flow is managed by a controller, each controller has several form pages, on each form page some data is updated in the session and flow goes to the next form page).
The problem is that some users are opening more than one tab to the application, each tab with a different step in the flow. At this point data in the session is messed up since the tabs share the same session (app uses cookie managed sessions).
Telling the users to use different browsers to avoid sharing the same session id (e.g. one Firefox window and one IE window) is not an option since surely at some point somebody will forget to do this and instead use tabs, thus messing up their data.
Adding some verifications that detect that another flow is requested from another tab and display a message to the user saying this is not allowed is not an option either since it pisses of the users and we don't want that do we? :D
The fact is that using another tab is useful for the users because they are more efficient in what they use the application for, so I am keeping this option. But the question now is how best to manage the one session data for the more tabs?
What I thought of, was to have the controller generate a token when it starts the flow and pass this token to each form page which in turn sends it back to identify itself. If another tab requests the same controller action when there is an ongoing flow then generate another token and pass that around.
Basically, I want each flow to have a token and inside the session I won't just keep one set of data but have a set of data for each token and then match requests based on the token.
Now the problem is that this approach will need a lot of rewritings to the application and I was wondering if there is a best practice for managing such a situation or can someone suggest other approaches. I am open to ideas.
Have you encountered this situation? How did you handle it?
This is usually done by assigning a windowId for each tab/window and passing it on each request. Jsf supports this via orchestra. Spring mvc will support it in the next version.
I recently needed this for a simple case, so I implemented it myself. Took half an hour. However, my scope was very limited:
pass a windowId with each request, and return it back for the next request. The first time - generate it.
for any attribute you want to store in the session, put a Map<String, Object> where the key is the windowId
This is exactly what Seam was created to handle. In Seam there's a concept called a Conversation which basically does exactly what you are explaining. Conversations are basically are a way to divide the Session into many pieces that can expire at some timeout. You can look at the source code for org.jboss.seam.core.Manager class to see how it's actually implemented and get inspired ;)
Depending on the complexity of your application, you may want to investigate implementing tabs within your application. This gives you wholesale control over the flow, while still providing users with the functionality they want. I'd argue it's, bugwise, the most robust solution, since you won't have a dependency on the way the browser handles sessions, minimising the number of "known unknowns".
Of course, there'll be potentially a large upfront cost to this, depending on how your application is structured. Without more information about your app, you're the best placed person to decide.
You can also try to wrap your application inside Adobe Air
And then limit your web application to be only accessable from this air. By doing this you dont need to consider the web browser fragmentation and their unique behaviour.
Good evening,
I am in the process of writing a Java Servlet (Struts 2, Tomcat, JSP etc) which is capable of doing some fairly complex simulations. These can take up to 2 minutes to complete on the and will return a graph of the results. It is trivial to calculate the percentage of the simulation completed because the process works by repeating the same calculations 1000s of times.
I would be interested to know if anyone has ever tried to use client side technology to provide any estimate of the percentage complete. I.e query the servlet processing to get the number of cycles completed at various point throughout the simulation. This could then be displayed as a bar in the client browser.
Any thoughts, advice, resources would be much appreciated.
Thanks,
Alex
In your database, have a table to maintain a list of simulations along with their server-calculated progress.
In your web-application, use AJAX to query the server every few seconds (1-20 depending on load is what I'd go with) and update a graphical progress bar. Most javascript libraries have simple timer-based AJAX functions to do exactly this sort of thing.
There's a few details to figure out, such as whether or not completed simulations remain in the DB (could be useful logging info), but overall, this should be fairly simple.
You could encapsulate your response in a mime/multipart message and sends your updates until you have a full response done.
Bugzilla uses this in their search to show "Searching ..."-screen until the searchresult is done.
If you want to use plain Struts2, you should take a look at the ExecuteAndWait Interceptor.
It works by the old refresh-with-timeout method. Sure, it has lower coolness factor than some AJAX thing, but it's simple and works (I've used it).
Struts2 takes care (by using this interceptor) of executing the action method (which would typically take a long time) in a separate thread, and it returns a special result wait until the work is completed. You just have to code a jsp that shows some "waiting..." message for this result, and make it refresh to the same action, repeatedly, with (say) two or three seconds of timeout. The jsp has access to the action properties, of course, hence you can code some getProgress() method to show a progress message or bar.
AJAX is the way to go here.