If an internet explorer user does Control+N (or File -> New -> Window), the spawned browser shares the same in-memory session cookie as the original browser, and therefore shares the same HttpSession memory space on the server. This can cause *tons* of problems, including data corruption.
Has anyone figured out a way to detect or prevent this?
The web is just a cheesy hack of an application platform, and what you point out is one of the biggest reasons why.
To enforce an order in your workflow, it is possible to detect "violations" of this order, eg. back buttons and opening new windows.
The classic way of doing this is to generate a token, place one copy of it in the session on the server and another copy of it in the page so it will be resubmitted in the request the next time the server receives a POST/GET from the user.
The tokens are then compared and if not equal, the user has got out of sync and some action can be taken.
Frameworks such as struts have this functionality built in, see the saveToken() and resetToken() methods (if my memory serves me right) in their API documentation for more details.
The problem with this is that the user may not actually be out of sequence, but may be doing two things in parallel that have no effect on each other, so you have to be very careful.
I worked on a project that did something similar to this, and we ended up having to totally remove that functionality, because of the user opened a link a new window, clicked around, and then closed it (leaving them back where they started, unbeknownst to the application), everything bombed (which is not an acceptable UI). As well, you could not use the back button to re-fill in a form. This is also not acceptable, IMO.
I guess the problem lies with the HTTP protocol being stateless. I suppose what you can do is implement your own state handling mechanism, by way of maybe an applet ? Or even if u want to, using flash as an intermediate client.
As you mention, the core of the problem lies in using browsers for applications.
Browsers were designed for navigating data, hence the problem.
Another hack you could try is to open the browser in "kiosk" mode (I only know this works with IE), in which the "page" takes up the whole screen and you can't see the toolbars at all, although of course this may not be appropriate for you depending on your application and your users.
So yes, it's all a cheesy hack, I see more apps. being done with Swing/other toolkits (even Micro$oft - shudder) in the future, as the tools/frameworks get better. A renaissance for the old fashioned (but richer) UI.
Yes, the only real solution is to just do a really good design and analysis of each page. For each page, list what pieces of data you expect to receive on input, and which you expect to provide on output. For each piece of data in the system, determine it's scope. If you have a lot in session scope, you are doing something wrong. Don't pollute session scope with a bunch of data. If data is needed for a 3-page transaction, use hidden fields or request parameters to keep it in it's proper scope and not junking up the session. Other than being a good design practice, this also mostly solves your browser problem, because each page is relatively self-contained, so if the user uses the back button, or goes off on some parallel adventure, when the return, you have everything you need.