“You should never go back” they said, and they were right. They probably weren't thinking about the problems of web application development when they said it though.
I've been struggling with the issue of handling the browser Back button correctly in a Struts application that I'm working on. The user is presented with a series of pages that make up a workflow process. I'm using an ActionForm with HTTP session scope because this is ideal for building wizard-style page flows, as the HTML form retains its values across multiple pages.
The problem comes if the user doesn't enter a value for one of the fields. Using the Struts validation features I can raise an ActionError that prompts the user to enter a value for that field. If the user then submits to the next page but then clicks the Back button, the error message is still there, only this time the field still has the valid value that was just entered! In other words, the application is now in a logically inconsistent state.
I've tried everything I can think of to solve this problem. The error message appears because the browser is returning a cached version of the page. I can turn off caching but then when the Back button is clicked the user gets that nasty IE page about the page being expired and needing to be refreshed. So they click the Refresh button and then they get a message dialogue that says that the page contains a form which requires that they click the Retry button to re-submit it. This returns them to the form and the errors are gone, only the values they entered are too. Hardly a slick user experience.
The Struts mailing list is full of messages from developers having similar problems, but I've not been able to find a definitive solution. Some misguided souls even ask if it's possible to disable the browser's Back button to avoid the problem entirely. Hint: people use web browsers all the time and are used to being able to go back—don't break their expectations of how the application is going to behave by attempting to cripple their browser. Sites such as Amazon let users jump to any point within the payment workflow as they please and everything is as you expect it to be, but then again, they use their own custom CGI solution. Are there any Struts meisters reading this who have the answer?
All of these problems stem from the fact that we're now using the stateless HTTP protocol for trying to deliver stateful applications. The technology behind the Web was designed to deliver static content. The browser-based application has been heralded as the solution to the problem of having to roll out traditional monolithic desktop applications to a large number of users within an organisation, and indeed it does solve this problem. It's also a great way to turn that shiny new 3 GHz computer on your desk into a dumb terminal.
Is offering an impoverished user experience by virtue of using this technology for something it was never designed for, really the best we can come up with?
Comments
There are 18 comments on this post. Comments are closed.
I couldn't agree more with your comments and I sympathize with your situation. I have encountered this situation numerous times before (although not with Struts) and never found a really elegant solution. What we've done in the past is place navigation buttons withing the application and plead with the user to only use those and not the Back button. Leaves me yearning for writing Windows apps again...
Problem: Multi-page forms requiring a specific workflow. Validating after every form page submit can cause problem when the user goes back (and forward again). Solution: Don't validate until all the steps (pages) are complete, and then only redisplay the invalid fields. Discussion: Workflows designed with multi-step interactions that must be executed through in a single, inflexible, order have been causing problems since the beginning of interactive computing. Users hate them, developers struggle with them. Wizard-like interactions are fine for some applications, where the system offer fine-grained control over the UI, but even then, no action is actually taken by the software until the last step of the wizard is completed. Complex application workflows are reminiscent of 3270-style screens. Just Don't Do It.
Crater Moon, that might just work! Normally I would hesitate to go down the route of redisplaying invalid fields right at the end, because as a user I'd prefer to be told about any errors there and then. However, in this case it's not a problem because there just aren't that many pages. It's not really a complex workflow but the pages have to be presented to the user in a certain order because the choices offered on later pages have a dependency on the selections made in earlier pages.
Here's one way to fix your problem-- a) disable the pre-defined back button. Lots of security concerns with Back, though I totally agree users are used to it and expect it. So you put your own back button on your jsp. That way instead of calling history.back() you call a struts-based action, forcing a re-post and any cached errors are lost. b) I believe at page load time you can override what the pre-defined back button does. It should be documented, though possibly obscurely. You may need to do a document.printAll (I don't remember the js/dhtml function name that prints the browser's js/dhtml buffers). If you still care, email me. Happy coding! Bill
Thanks for your suggestions Bill. I'm going to try Crater Moon's suggestion first. As I said in the article, I'd rather try to fix my application than "fix" the browser. Happy holidays! :-)
Always respond POST with a redirect. When you get the POST, process the request and send a redirect to the page the user sees. If the user refreshes an expired version of that page, it is not a form submit and they will not be prompted for anything.
Any idea how I do that using Struts, Brendan?
I know this is an old post, and that I'm not a programmer, but I wonder if perhaps you couldn't just launch your application in a pop up window that has none of the toolbars visible? It would look like a separate Windows application, and you could put any interface widgets you wanted to within the UI of your program without worrying about people clicking the hidden "Back" button. I know a lot of folks hate pop ups, but isn't it because they're normally advertising? I certainly don't mind when a website pops open a new window that I requested by clicking a link.
Richard, It's a nice idea but they're are some problems with it. First of all, research has shown that users get confused by pop-up windows. They lose track of where they are. Secondly, what to do about the main browser window that gets left behind? Finally, you can disable the toolbar in the pop-up window but that doesn't solve the problem becuase users can still right-click and select Back, or hit Backspace in IE etc. I actually didn't want to use pop-ups windows in my comments system for this site but I didn't have time to develop an alternative. It's something I'll have to revisit when it's time for the inevitable redesign.
Back button... I hate it, too!
I don't know if it's too late to give you a solution. Anyway, i found a Struts extension that solves the problem. It's called: "Struts workflow extension" and you can find it in: http://www.livinglogic.de/Struts/
Thanks Juan, I'll check it out.
I hate back button
Hi John, I am having the same problem too, please advise if you were successful in finding a solution. Thanks, Bob
Hi Bob, Unfortunately there is no silver bullet solution.
I am having the same problem with the back button and it hapens only on a few of the pages - no idea why.
Same problem happens to me too. What about the plugin in the post by Juan Manuel Caicedo (Struts Workflow extension...)? Did anyone try it out?
I face the same problem. I have written code so that the pages are not cached on browser and on click of back buton, the user session times out and he is loged out. But this does not work with OS Windows XP and IE 6.0 .. Need a solution for this, if anyone has